2023-01-20 14:40:45 +01:00
function getPixelRGBValues ( base64Image ) {
httpArray = [ ] ;
2023-01-23 11:41:41 +01:00
fileJSON = ` {"on":true,"bri": ${ gId ( 'brightnessNumber' ) . value } ,"seg":{"id": ${ gId ( 'targetSegment' ) . value } ,"i":[ ` ;
2023-01-21 16:33:59 +01:00
//Which object holds the secret to the segment ID
const segm = gId ( 'targetSegment' ) ;
let segID = 0 ;
if ( segm . style . display == "flex" ) {
segID = segm . value
} else {
segID = gId ( 'segID' ) . value ;
}
2023-01-20 14:40:45 +01:00
2023-01-20 22:33:30 +01:00
//const copyJSONledbutton = gId('copyJSONledbutton');
const JSONled = gId ( 'JSONled' ) ;
2023-01-23 11:41:41 +01:00
const maxNoOfColorsInCommandSting = parseInt ( gId ( 'colorLimitNumber' ) . value ) ;
2023-01-20 14:40:45 +01:00
let hybridAddressing = false ;
let selectedIndex = - 1 ;
2023-01-20 22:33:30 +01:00
let selector = gId ( "formatSelector" ) ;
2023-01-20 14:40:45 +01:00
selectedIndex = selector . selectedIndex ;
const formatSelection = selector . options [ selectedIndex ] . value ;
2023-01-20 22:33:30 +01:00
selector = gId ( "ledSetupSelector" ) ;
2023-01-20 14:40:45 +01:00
selectedIndex = selector . selectedIndex ;
const ledSetupSelection = selector . options [ selectedIndex ] . value ;
2023-01-20 22:33:30 +01:00
selector = gId ( "colorFormatSelector" ) ;
2023-01-20 14:40:45 +01:00
selectedIndex = selector . selectedIndex ;
let hexValueCheck = true ;
if ( selector . options [ selectedIndex ] . value == 'dec' ) {
hexValueCheck = false
}
2023-01-20 22:33:30 +01:00
selector = gId ( "addressingSelector" ) ;
2023-01-20 14:40:45 +01:00
selectedIndex = selector . selectedIndex ;
let segmentValueCheck = true ; //If Range or Hybrid
if ( selector . options [ selectedIndex ] . value == 'single' ) {
segmentValueCheck = false
} else if ( selector . options [ selectedIndex ] . value == 'hybrid' ) {
hybridAddressing = true ;
}
let curlString = ''
let haString = ''
2023-01-23 11:41:41 +01:00
let colorSeparatorStart = '"' ;
let colorSeparatorEnd = '"' ;
2023-01-20 14:40:45 +01:00
if ( ! hexValueCheck ) {
colorSeparatorStart = '[' ;
colorSeparatorEnd = ']' ;
}
// Warnings
let hasTransparency = false ; //If alpha < 255 is detected on any pixel, this is set to true in code below
let imageInfo = '' ;
// Create an off-screen canvas
2023-01-20 22:33:30 +01:00
var canvas = cE ( 'canvas' ) ;
2023-01-22 18:47:34 +01:00
var context = canvas . getContext ( '2d' , { willReadFrequently : true } ) ;
2023-01-20 14:40:45 +01:00
// Create an image element and set its src to the base64 image
var image = new Image ( ) ;
image . src = base64Image ;
// Wait for the image to load before drawing it onto the canvas
image . onload = function ( ) {
2023-01-21 16:33:59 +01:00
let scalePath = gId ( "scaleDiv" ) . children [ 0 ] . children [ 0 ] ;
2023-01-20 14:40:45 +01:00
let color = scalePath . getAttribute ( "fill" ) ;
2023-01-20 22:33:30 +01:00
let sizeX = gId ( "sizeX" ) . value ;
let sizeY = gId ( "sizeY" ) . value ;
2023-01-20 14:40:45 +01:00
if ( color != accentColor || sizeX < 1 || sizeY < 1 ) {
//image will not be rezised Set desitred size to original size
sizeX = image . width ;
sizeY = image . height ;
2023-01-22 18:47:34 +01:00
//failsafe for not generating huge images automatically
if ( image . width > 512 || image . height > 512 )
{
sizeX = 16 ;
sizeY = 16 ;
}
2023-01-20 14:40:45 +01:00
}
// Set the canvas size to the same as the desired image size
canvas . width = sizeX ;
canvas . height = sizeY ;
imageInfo = '<p>Width: ' + sizeX + ', Height: ' + sizeY + ' (make sure this matches your led matrix setup)</p>'
// Draw the image onto the canvas
context . drawImage ( image , 0 , 0 , sizeX , sizeY ) ;
// Get the pixel data from the canvas
var pixelData = context . getImageData ( 0 , 0 , sizeX , sizeY ) . data ;
// Create an array to hold the RGB values of each pixel
var pixelRGBValues = [ ] ;
// If the first row of the led matrix is right -> left
let right2leftAdjust = 1 ;
if ( ledSetupSelection == 'l2r' ) {
right2leftAdjust = 0 ;
}
// Loop through the pixel data and get the RGB values of each pixel
for ( var i = 0 ; i < pixelData . length ; i += 4 ) {
var r = pixelData [ i ] ;
var g = pixelData [ i + 1 ] ;
var b = pixelData [ i + 2 ] ;
var a = pixelData [ i + 3 ] ;
let pixel = i / 4
let row = Math . floor ( pixel / sizeX ) ;
let led = pixel ;
if ( ledSetupSelection == 'matrix' ) {
//Do nothing, the matrix is set upp like the index in the image
//Every row starts from the left, i.e. no zigzagging
}
else if ( ( row + right2leftAdjust ) % 2 === 0 ) {
//Setup is traditional zigzag
//right2leftAdjust basically flips the row order if = 1
//Row is left to right
//Leave led index as pixel index
} else {
//Setup is traditional zigzag
//Row is right to left
//Invert index of row for led
let indexOnRow = led - ( row * sizeX ) ;
let maxIndexOnRow = sizeX - 1 ;
let reversedIndexOnRow = maxIndexOnRow - indexOnRow ;
led = ( row * sizeX ) + reversedIndexOnRow ;
}
// Add the RGB values to the pixel RGB values array
pixelRGBValues . push ( [ r , g , b , a , led , pixel , row ] ) ;
}
pixelRGBValues . sort ( ( a , b ) => a [ 5 ] - b [ 5 ] ) ;
//Copy the values to a new array for resorting
let ledRGBValues = [ ... pixelRGBValues ] ;
//Sort the array based on led index
ledRGBValues . sort ( ( a , b ) => a [ 4 ] - b [ 4 ] ) ;
//Generate JSON in WLED format
let JSONledString = '' ;
//Set starting values for the segment check to something that is no color
let segmentStart = - 1 ;
let maxi = ledRGBValues . length ;
let curentColorIndex = 0
let commandArray = [ ] ;
//For evry pixel in the LED array
for ( let i = 0 ; i < maxi ; i ++ ) {
let pixel = ledRGBValues [ i ] ;
let r = pixel [ 0 ] ;
let g = pixel [ 1 ] ;
let b = pixel [ 2 ] ;
let a = pixel [ 3 ] ;
let segmentString = '' ;
let segmentEnd = - 1 ;
if ( segmentValueCheck ) {
if ( segmentStart < 0 ) {
//This is the first led of a new segment
segmentStart = i ;
} //Else we allready have a start index
if ( i < maxi - 1 ) {
let iNext = i + 1 ;
let nextPixel = ledRGBValues [ iNext ] ;
if ( nextPixel [ 0 ] != r || nextPixel [ 1 ] != g || nextPixel [ 2 ] != b ) {
//Next pixel has new color
//The current segment ends with this pixel
segmentEnd = i + 1 //WLED wants the NEXT LED as the stop led...
if ( segmentStart == i && hybridAddressing ) {
//If only one led/pixel, no segment info needed
if ( JSONledString == '' ) {
//If addressing is single, we need to start every command with a starting possition
segmentString = '' + i + ',' ;
//Fixed to b2
} else {
segmentString = ''
}
}
else {
segmentString = segmentStart + ',' + segmentEnd + ',' ;
}
}
} else {
//This is the last pixel, so the segment must end
segmentEnd = i + 1 ;
if ( segmentStart + 1 == segmentEnd && hybridAddressing ) {
//If only one led/pixel, no segment info needed
if ( JSONledString == '' ) {
//If addressing is single, we need to start every command with a starting possition
segmentString = '' + i + ',' ;
//Fixed to b2
} else {
segmentString = ''
}
}
else {
segmentString = segmentStart + ',' + segmentEnd + ',' ;
}
}
} else {
//Write every pixel
if ( JSONledString == '' ) {
//If addressing is single, we need to start every command with a starting possition
JSONledString = i
//Fixed to b2
}
segmentStart = i
segmentEnd = i
//Segment string should be empty for when addressing single. So no need to set it again.
}
if ( a < 255 ) {
hasTransparency = true ; //If ANY pixel has alpha < 255 then this is set to true to warn the user
}
if ( segmentEnd > - 1 ) {
//This is the last pixel in the segment, write to the JSONledString
//Return color value in selected format
let colorValueString = r + ',' + g + ',' + b ;
if ( hexValueCheck ) {
const [ red , green , blue ] = [ r , g , b ] ;
colorValueString = ` ${ [ red , green , blue ] . map ( x => x . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) } ` ;
} else {
//do nothing, allready set
}
// Check if start and end is the same, in which case remove
2023-01-23 11:41:41 +01:00
JSONledString += segmentString + colorSeparatorStart + colorValueString + colorSeparatorEnd ;
2023-01-20 14:40:45 +01:00
fileJSON = JSONledString + segmentString + colorSeparatorStart + colorValueString + colorSeparatorEnd ;
curentColorIndex = curentColorIndex + 1 ; // We've just added a new color to the string so up the count with one
if ( curentColorIndex % maxNoOfColorsInCommandSting === 0 || i == maxi - 1 ) {
//If we have accumulated the max number of colors to send in a single command or if this is the last pixel, we should write the current colorstring to the array
commandArray . push ( JSONledString ) ;
JSONledString = '' ; //Start on an new command string
} else
{
//Add a comma to continue the command string
JSONledString = JSONledString + ','
}
//Reset segment values
segmentStart = - 1 ;
}
}
JSONledString = ''
2023-01-23 11:41:41 +01:00
//For every commandString in the array
2023-01-20 14:40:45 +01:00
for ( let i = 0 ; i < commandArray . length ; i ++ ) {
2023-01-23 11:41:41 +01:00
let thisJSONledString = ` {"on":true,"bri": ${ gId ( 'brightnessNumber' ) . value } ,"seg":{"id": ${ segID } ,"i":[ ${ commandArray [ i ] } ]}} ` ;
2023-01-20 14:40:45 +01:00
httpArray . push ( thisJSONledString ) ;
2023-01-23 11:41:41 +01:00
let thiscurlString = ` curl -X POST "http:// ${ gId ( 'curlUrl' ) . value } /json/state" -d \' ${ thisJSONledString } \' -H "Content-Type: application/json" ` ;
2023-01-20 14:40:45 +01:00
//Aggregated Strings That should be returned to the user
if ( i > 0 ) {
JSONledString = JSONledString + '\n' ;
curlString = curlString + ' && ' ;
}
2023-01-23 11:41:41 +01:00
JSONledString += thisJSONledString ;
curlString += thiscurlString ;
2023-01-20 14:40:45 +01:00
}
2023-01-23 11:41:41 +01:00
haString = ` #Uncomment if you don \' t allready have these defined in your switch section of your configuration.yaml
# - platform : command _line
# switches :
$ { gId ( 'haID' ) . value }
friendly _name : $ { gId ( 'haName' ) . value }
unique _id : $ { gId ( 'haUID' ) . value }
command _on : >
$ { curlString }
command _off : >
curl - X POST "http://${gId('curlUrl').value}/json/state" - d \ '{"on":false}\' - H "Content-Type: application/json" ` ;
2023-01-20 14:40:45 +01:00
if ( formatSelection == 'wled' ) {
JSONled . value = JSONledString ;
} else if ( formatSelection == 'curl' ) {
JSONled . value = curlString ;
} else if ( formatSelection == 'ha' ) {
JSONled . value = haString ;
} else {
JSONled . value = 'ERROR!/n' + formatSelection + ' is an unknown format.'
}
2023-01-23 11:41:41 +01:00
fileJSON += ']}}' ;
2023-01-20 14:40:45 +01:00
2023-01-20 22:33:30 +01:00
let infoDiv = gId ( 'image-info' ) ;
let canvasDiv = gId ( 'image-info' ) ;
2023-01-20 14:40:45 +01:00
if ( hasTransparency ) {
imageInfo = imageInfo + '<p><b>WARNING!</b> Transparency info detected in image. Transparency (alpha) has been ignored. To ensure you get the result you desire, use only solid colors in your image.</p>'
}
infoDiv . innerHTML = imageInfo ;
canvasDiv . style . display = "block"
//Drawing the image
drawBoxes ( pixelRGBValues , sizeX , sizeY ) ;
}
}