Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
node-red-contrib-image-output
Advanced tools
Easy way of previewing and examining images in your flows
Simple image output node. Useful for previewing images (of face detecting, object recognition etc...) inside the Node-RED flow editor.
The expected input should be a jpg or png image, which need to be delivered in one of the following formats:
Either use the Editor - Menu - Manage Palette - Install option, or run the following npm command in your Node-RED user directory (typically ~/.node-red
):
npm i node-red-contrib-image-output
This node can be used to preview images inside the Node-RED flow editor. The following examples explain how the different kind of input image formats can be visualized. All these example flows are also available via the 'Import' menu in the Node-RED flow editor.
Apply an image as a binary Buffer (i.e. bits and bytes ...):
[{"id":"46ffc819.b736f8","type":"http request","z":"30fb1577.8f556a","name":"","method":"GET","ret":"bin","paytoqs":false,"url":"https://dummyimage.com/200x150/000/fff&text={{{payload}}}","tls":"","persist":false,"proxy":"","authType":"","x":610,"y":640,"wires":[["d603e881.2fa1c8"]]},{"id":"25d928c1.708098","type":"inject","z":"30fb1577.8f556a","name":"Generate next image","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":640,"wires":[["878f8ec1.effe4"]]},{"id":"878f8ec1.effe4","type":"function","z":"30fb1577.8f556a","name":"image counter","func":"var count = flow.get(\"count\")||0;\n\ncount++;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Image \" + count});\n\n// Save the new value back to context so it will be available next time\nflow.set('count',count);\n\n// Update the message payload and return - no need to create a new msg\nmsg.payload = \"Image \" + count;\nreturn msg;","outputs":1,"noerr":0,"x":420,"y":640,"wires":[["46ffc819.b736f8"]]},{"id":"d603e881.2fa1c8","type":"image","z":"30fb1577.8f556a","name":"","width":160,"data":"payload","dataType":"msg","thumbnail":true,"active":true,"x":800,"y":640,"wires":[]}]
Apply an image as a base64 encoded string:
[{"id":"46ffc819.b736f8","type":"http request","z":"30fb1577.8f556a","name":"","method":"GET","ret":"bin","paytoqs":false,"url":"https://dummyimage.com/200x150/000/fff&text={{{payload}}}","tls":"","persist":false,"proxy":"","authType":"","x":610,"y":640,"wires":[["27a53fad.5c768"]]},{"id":"25d928c1.708098","type":"inject","z":"30fb1577.8f556a","name":"Generate next image","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":640,"wires":[["878f8ec1.effe4"]]},{"id":"878f8ec1.effe4","type":"function","z":"30fb1577.8f556a","name":"image counter","func":"var count = flow.get(\"count\")||0;\n\ncount++;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Image \" + count});\n\n// Save the new value back to context so it will be available next time\nflow.set('count',count);\n\n// Update the message payload and return - no need to create a new msg\nmsg.payload = \"Image \" + count;\nreturn msg;","outputs":1,"noerr":0,"x":420,"y":640,"wires":[["46ffc819.b736f8"]]},{"id":"27a53fad.5c768","type":"base64","z":"30fb1577.8f556a","name":"","action":"str","property":"payload","x":780,"y":640,"wires":[["d603e881.2fa1c8"]]},{"id":"d603e881.2fa1c8","type":"image","z":"30fb1577.8f556a","name":"","width":160,"data":"payload","dataType":"msg","thumbnail":true,"active":true,"x":960,"y":640,"wires":[]}]
Apply an image as a Jimp object. This node allows Jimp images to be previewed, which are send by other Jimp related nodes. The following example shows a Jimp image, generated by the node-red-contrib-image-tools nodes:
Note: the node-red-contrib-image-tools
node should be installed, prior to importing this example.
[{"id":"27719e17.2169f2","type":"jimp-image","z":"30fb1577.8f556a","name":"","data":"payload","dataType":"msg","ret":"img","parameter1":"","parameter1Type":"msg","parameter2":"","parameter2Type":"msg","parameter3":"","parameter3Type":"msg","parameter4":"","parameter4Type":"msg","parameter5":"","parameter5Type":"msg","parameter6":"","parameter6Type":"msg","parameter7":"","parameter7Type":"msg","parameter8":"","parameter8Type":"msg","parameterCount":0,"jimpFunction":"none","selectedJimpFunction":{"name":"none","fn":"none","description":"Just loads the image.","parameters":[]},"x":770,"y":640,"wires":[["d603e881.2fa1c8"]]},{"id":"46ffc819.b736f8","type":"http request","z":"30fb1577.8f556a","name":"","method":"GET","ret":"bin","paytoqs":false,"url":"https://dummyimage.com/200x150/000/fff&text={{{payload}}}","tls":"","persist":false,"proxy":"","authType":"","x":610,"y":640,"wires":[["27719e17.2169f2"]]},{"id":"25d928c1.708098","type":"inject","z":"30fb1577.8f556a","name":"Generate next image","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":640,"wires":[["878f8ec1.effe4"]]},{"id":"878f8ec1.effe4","type":"function","z":"30fb1577.8f556a","name":"image counter","func":"var count = flow.get(\"count\")||0;\n\ncount++;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Image \" + count});\n\n// Save the new value back to context so it will be available next time\nflow.set('count',count);\n\n// Update the message payload and return - no need to create a new msg\nmsg.payload = \"Image \" + count;\nreturn msg;","outputs":1,"noerr":0,"x":420,"y":640,"wires":[["46ffc819.b736f8"]]},{"id":"d603e881.2fa1c8","type":"image","z":"30fb1577.8f556a","name":"","width":160,"data":"payload","dataType":"msg","thumbnail":true,"active":true,"x":960,"y":640,"wires":[]}]
When the node is currently displaying an image, that image can be hidden via those values:
null
image (e.g. msg.payload = null
).delete msg.payload
).msg.payload = ""
).The following demo hides the previewed image based on the msg.payload
:
[{"id":"acae4788.db10e8","type":"http request","z":"e2675d9d.6854e","name":"","method":"GET","ret":"bin","paytoqs":false,"url":"https://dummyimage.com/200x150/000/fff&text={{{payload}}}.jpg","tls":"","persist":false,"proxy":"","authType":"","x":570,"y":360,"wires":[["b548876a.e2f8b8"]]},{"id":"8ff5f74b.d2efb8","type":"inject","z":"e2675d9d.6854e","name":"Generate next image","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":360,"wires":[["ea222193.08df9"]]},{"id":"ea222193.08df9","type":"function","z":"e2675d9d.6854e","name":"image counter","func":"var count = flow.get(\"count\")||0;\n\ncount++;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Image \" + count});\n\n// Save the new value back to context so it will be available next time\nflow.set('count',count);\n\n// Update the message payload and return - no need to create a new msg\nmsg.payload = \"Image \" + count;\nreturn msg;","outputs":1,"noerr":0,"x":400,"y":360,"wires":[["acae4788.db10e8"]]},{"id":"670b37d4.e67658","type":"inject","z":"e2675d9d.6854e","name":"Msg without payload","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":470,"y":260,"wires":[["6d9c5aa.2d5e6a4"]]},{"id":"b548876a.e2f8b8","type":"base64","z":"e2675d9d.6854e","name":"","action":"","property":"payload","x":720,"y":360,"wires":[["f8d56b3b.3bb1f8"]]},{"id":"6d9c5aa.2d5e6a4","type":"change","z":"e2675d9d.6854e","name":"","rules":[{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":260,"wires":[["f8d56b3b.3bb1f8"]]},{"id":"636d9da2.959fb4","type":"inject","z":"e2675d9d.6854e","name":"Msg with empty string","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":460,"y":300,"wires":[["6dce2d91.6158f4"]]},{"id":"c6c47147.1972a","type":"inject","z":"e2675d9d.6854e","name":"Msg with null value","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":470,"y":220,"wires":[["d21096f2.632ed8"]]},{"id":"6dce2d91.6158f4","type":"change","z":"e2675d9d.6854e","name":"msg.payload = \"\"","rules":[{"t":"set","p":"payload","pt":"msg","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":300,"wires":[["f8d56b3b.3bb1f8"]]},{"id":"d21096f2.632ed8","type":"function","z":"e2675d9d.6854e","name":"msg.payload = null","func":"msg.payload = null;\nreturn msg;","outputs":1,"noerr":0,"x":690,"y":220,"wires":[["f8d56b3b.3bb1f8"]]},{"id":"b99d140c.ce4448","type":"comment","z":"e2675d9d.6854e","name":"Multiple ways to hide the preview image:","info":"","x":520,"y":180,"wires":[]},{"id":"f8d56b3b.3bb1f8","type":"image","z":"e2675d9d.6854e","name":"","width":160,"data":"payload","dataType":"msg","thumbnail":false,"active":true,"x":920,"y":360,"wires":[]}]
Via the button on the right side, the image stream can be stopped or (re)started again:
Remark: the server will stop sending images to the client, so there will be no more data traffic involved!
The width (in pixels) that the image needs to be displayed in the flow. The height will be calculated automatically, with the same aspect ratio as the original image.
Specify how the input image will be delivered to this node. By default the image needs to be delivered in the msg.payload
of the input message.
By transferring smaller images the bandwith can be reduced, i.e. the number of bytes that is being send across the network. When too much data is pushed (across the websocket), the flow editor can become unresponsive.
Caution: resizing images on the server will require server-side CPU usage. So it has to be decided what is prefered: lower bandwidth or lower cpu usage on the server. This decision will depend on the use case and hardware...
When selected this adds an output wire to the node in order to pass the original message through to a following node. This performs better than forking the wires, however it does remove the enable/disable button.
FAQs
Easy way of previewing and examining images in your flows
We found that node-red-contrib-image-output demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.