# How can I load image file into the RGB array?

**URL:** <https://discourse.nodered.org/t/how-can-i-load-image-file-into-the-rgb-array/16670>\
**Category:** General\
**Created:** [14 October 2019 01:38 UTC](https://discourse.nodered.org/t/how-can-i-load-image-file-into-the-rgb-array/16670 "2019-10-14T01:38:23Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![ded\_banzai](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ded_banzai/32/13179_2.png) [@ded\_banzai](https://discourse.nodered.org/u/ded_banzai)\
**Post date:** [14 October 2019 01:38 UTC](https://discourse.nodered.org/t/how-can-i-load-image-file-into-the-rgb-array/16670/1 "2019-10-14T01:38:23Z")

</div>

I am trying to play with 16x16 WS2812B LED Matix controlled by ESP8266 with WLED firmware. It allows controlling it with UDP packets which are simply the sequence of R,G,B values. For example first three pixels where first is red, second is green and third is blue are encoded like this: [0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff]). The first challenge I faced is how to load image (16x16 png/jpg/bmp etc...) into the Node-Red as binary buffer array. I tried node-red-contrib-image-tools's image node, but it looks like it just reads image byte-by-byte without decoding it into RGB buffer. Are there any nodes for this? Also ideally, it should also be able to reverse each even line of the array (without reversing RGB values) - the matrix has snake topology.

I will appreciate any help/ideas/suggestions.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [14 October 2019 09:56 UTC](https://discourse.nodered.org/t/how-can-i-load-image-file-into-the-rgb-array/16670/2 "2019-10-14T09:56:14Z")

</div>

Hi, I wrote `node-red-contrib-image-tools` so I know a thing or two 😉

It most definitely does decode the image & you can get access to the underlying RGB components.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/f/f5be3e2fb356e9614d70678132f589e00e8ba999.png)

```auto
[{"id":"a6f53bfd.0ec578","type":"jimp-image","z":"23406c97.6c35b4","name":"","data":"payload","dataType":"msg","ret":"img","parameter1":"img.bmp","parameter1Type":"str","parameter2":"","parameter2Type":"num","parameter3":"","parameter3Type":"num","parameter4":"","parameter4Type":"none","parameter5":"","parameter5Type":"none","parameter6":"","parameter6Type":"none","parameter7":"","parameter7Type":"none","parameter8":"","parameter8Type":"msg","parameterCount":0,"jimpFunction":"none","selectedJimpFunction":{"name":"none","fn":"none","description":"Just loads the image.","parameters":[]},"x":270,"y":900,"wires":[["7add4a7d.cbfb44","963690a7.e111"]]},{"id":"8c1ef7f6.812678","type":"inject","z":"23406c97.6c35b4","name":"16x16 pokeball","topic":"pokeball","payload":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACCSURBVDhPrZAJDoAwCAR5Ok/rz6pFFxekxmuTMS3HNFF6EREpqRKqPjihEvntajHDEjuNgtLAHSCx7yfBm2Uwdv8TVBLUZw+4gCUMelWfeqtt+xmPoJ2jkMODOdizjl8eYrsQqKrRWnPyMCcIRliSRRkWBjVeYxGDPife9mAwc07vCzBBNxZvGWrwAAAAAElFTkSuQmCC","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":900,"wires":[["a6f53bfd.0ec578"]]},{"id":"36c268c9.66fb18","type":"debug","z":"23406c97.6c35b4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":790,"y":960,"wires":[]},{"id":"7add4a7d.cbfb44","type":"function","z":"23406c97.6c35b4","name":"getRBG from Pixels (sync)","func":"let rgb = []\nlet image = msg.payload;\nfor(let x = 0; x < image.bitmap.width; x++){\n for(let y = 0; y < image.bitmap.height; y++){ \n let color = image.getPixelColor(x, y) ;\n var r = (color >> 16) & 255; \n var g = (color >> 8) & 255; \n var b = color & 255; \n rgb.push(r);\n rgb.push(g);\n rgb.push(b);\n }\n}\n\nmsg.rgb = rgb;\nreturn msg;","outputs":1,"noerr":0,"x":480,"y":960,"wires":[["4e3ff0a0.8ccbc"]]},{"id":"4e3ff0a0.8ccbc","type":"image viewer","z":"23406c97.6c35b4","name":"","width":"64","data":"payload","dataType":"msg","x":670,"y":960,"wires":[["36c268c9.66fb18"]]},{"id":"963690a7.e111","type":"function","z":"23406c97.6c35b4","name":"getRBG from Pixels (async)","func":"\nvar image = msg.payload;\nvar rgb = [];\nimage.scan(0, 0, image.bitmap.width, image.bitmap.height, function(x, y, idx) {\n // x, y is the position of this pixel on the image\n // idx is the position start position of this rgba tuple in the bitmap Buffer\n \n var r = this.bitmap.data[idx + 0];\n var g = this.bitmap.data[idx + 1];\n var b = this.bitmap.data[idx + 2];\n var a = this.bitmap.data[idx + 3];\n rgb.push(r);\n rgb.push(g);\n rgb.push(b); \n if (x >= image.bitmap.width - 1 && y >= image.bitmap.height - 1) {\n // image scan finished, do your stuff\n node.send({topic:\"rgb\",payload: rgb})\n }\n});\n","outputs":1,"noerr":0,"x":480,"y":840,"wires":[["28ac1e3a.feadc2"]]},{"id":"28ac1e3a.feadc2","type":"debug","z":"23406c97.6c35b4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":790,"y":840,"wires":[]},{"id":"f25e6bf2.8d2a78","type":"comment","z":"23406c97.6c35b4","name":"To load a file chage the inject to send filename","info":"","x":210,"y":780,"wires":[]},{"id":"c40b7bc3.139098","type":"comment","z":"23406c97.6c35b4","name":"RGB Data will be in msg.payload","info":"","x":870,"y":880,"wires":[]},{"id":"744fa2e9.617fbc","type":"comment","z":"23406c97.6c35b4","name":"RGB Data will be in msg.rgb","info":"","x":860,"y":1000,"wires":[]}]

```

EDIT...  
Added this to flow library - [https://flows.nodered.org/flow/1a867a5280c2cd5a2304ca8db567ec64](https://flows.nodered.org/flow/1a867a5280c2cd5a2304ca8db567ec64)

---

<div class="post-metadata">

**Author:** ![cymplecy](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cymplecy/32/2773_2.png) [@cymplecy](https://discourse.nodered.org/u/cymplecy)\
**Post date:** [14 October 2019 14:19 UTC](https://discourse.nodered.org/t/how-can-i-load-image-file-into-the-rgb-array/16670/4 "2019-10-14T14:19:05Z")

</div>

@Steve-Mcl  
I've been playing around with this (as I've been after something for a while to get at bitmaps) and I think there are a couple of issues with your sync function and I've produced this version

```auto
let rgb = []
let image = msg.payload;
for(let y = 0; y < image.bitmap.height; y++){    
    for(let x = 0; x < image.bitmap.width; x++){
        let color = image.getPixelColor(x, y) ;
        var r = (color >> 24) & 255; 
        var g = (color >> 16) & 255; 
        var b = (color >> 8) & 255; 
        rgb.push(r);
        rgb.push(g);
        rgb.push(b);
    }
}

msg.rgb = rgb;
return msg;

```

I swapped the for x/y around so that it does rows then columns  
Also, I think the image.getPixelColor(x, y) is returning a 4 byte value with alpha as well as RGB so I've altered that bit as well

I've not looked at the async code as async JS just confuses me 🙂

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [14 October 2019 16:13 UTC](https://discourse.nodered.org/t/how-can-i-load-image-file-into-the-rgb-array/16670/5 "2019-10-14T16:13:59Z")

</div>

> [@cymplecy](#):
>
> eturning a 4 byte value with alpha

Yes it does but I left that out for the OP.

Good spot on swapping the X & Y around 👍

---

<div class="post-metadata">

**Author:** ![cymplecy](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cymplecy/32/2773_2.png) [@cymplecy](https://discourse.nodered.org/u/cymplecy)\
**Post date:** [14 October 2019 16:17 UTC](https://discourse.nodered.org/t/how-can-i-load-image-file-into-the-rgb-array/16670/6 "2019-10-14T16:17:01Z")

</div>

> [@Steve-Mcl](#):
>
> Yes it does but I left that out for the OP.

I meant you returned the wrong bytes - I haven't added in the alpha value 🙂

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [14 October 2019 16:27 UTC](https://discourse.nodered.org/t/how-can-i-load-image-file-into-the-rgb-array/16670/7 "2019-10-14T16:27:31Z")

</div>

Haha another good spot. Cheers.

Off my game today.

---

<div class="post-metadata">

**Author:** ![cymplecy](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cymplecy/32/2773_2.png) [@cymplecy](https://discourse.nodered.org/u/cymplecy)\
**Post date:** [14 October 2019 16:46 UTC](https://discourse.nodered.org/t/how-can-i-load-image-file-into-the-rgb-array/16670/8 "2019-10-14T16:46:57Z")

</div>

I'm just pleased to have found out that the node returns the bitmap - like the OP, I'd looked into it in the past and didn't notice that it did.

Great work 🙂

---

<div class="post-metadata">

**Author:** ![ded\_banzai](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ded_banzai/32/13179_2.png) [@ded\_banzai](https://discourse.nodered.org/u/ded_banzai)\
**Post date:** [14 October 2019 20:46 UTC](https://discourse.nodered.org/t/how-can-i-load-image-file-into-the-rgb-array/16670/9 "2019-10-14T20:46:43Z")

</div>

Hi Steve, thank you very much for your very helpful reply! I will update here about the results in a few days. And thank you so much for the node - awesome job, man!

---

<div class="post-metadata">

**Author:** ![ded\_banzai](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ded_banzai/32/13179_2.png) [@ded\_banzai](https://discourse.nodered.org/u/ded_banzai)\
**Post date:** [15 October 2019 03:24 UTC](https://discourse.nodered.org/t/how-can-i-load-image-file-into-the-rgb-array/16670/10 "2019-10-15T03:24:57Z")

</div>

It works! I slightly modified code to reverse each even line (ugliest way of course, I am not coder at all):

```auto
let rgb = []
let image = msg.payload;
for(let y = 0; y < image.bitmap.height; y+=2){
    for(let x = image.bitmap.width; x > 0; x--){
        color = image.getPixelColor(x-1, y) ;
        r = (color >> 24) & 255; 
        g = (color >> 16) & 255; 
        b = (color >> 8) & 255; 
        rgb.push(r);
        rgb.push(g);
        rgb.push(b);
    }
    for(let x = 0; x < image.bitmap.width; x++){
        color = image.getPixelColor(x, y+1) ;
        r = (color >> 24) & 255; 
        g = (color >> 16) & 255; 
        b = (color >> 8) & 255; 
        rgb.push(r);
        rgb.push(g);
        rgb.push(b);
    }
}
msg.rgb = rgb;
msg.rgbBuffer = Buffer.from(rgb);
return msg;

```

Thank you both [Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl) and [cymplecy](https://discourse.nodered.org/u/cymplecy). Now I can directly control LED matrix from Node-Red by sending .rgbBuffer directly to the matrix's UDP port. .
