How to Merge 8 PNGs into 1 PNG?

Hey everyone,

So I have essentially 8 png files at urls, that are 284px by 284px each,
I want to stack them ontop of each other like layer so to speak and then save the composite as a single new png file.

I've already figure out how to stack them via DIVs in dashboard, but that doesn't actually produce a composited file obviously.

Can this be done?
Note: I found merge-images - npm but I wasn't able to use it probably cuz i wasn't doing something right.

Hopefully you two don't mind me tagging you @UnborN and @E1cid
You both seem to be very clever and I suspect this would be easy for either of you.

If ANYONE can help on this would be greatly appreciated!

Thanks!

I don't understand the use case... (aside from the already mentioned merge-images)

Perhaps showing what you have tried with that option? (and how it relates to Node-Red)

The search box is your friend...

2 Likes

So I tried to use the sample but apparently its missing a module?

I was able to piece together something but I can't get the actual composite function to work.

I can pass in image urls and then view them individually but not as a composite.
here is a quick flow that will inject a string that gets evaluated and some of the values are used to define the URLs of the images to composite.

[{"id":"c6bb800b.58df5","type":"inject","z":"443abc3f.d3eea4","name":"inject principal","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"SP9JYG8J36SXDMWY2X5RJSBQZ1FZQW4YDF7SPB51","payloadType":"str","x":190,"y":600,"wires":[["f73bf102.ca409","65f0d03.ff2bb3"]]},{"id":"65f0d03.ff2bb3","type":"function","z":"443abc3f.d3eea4","name":"create Image URLs","func":"var depositaddress = msg.payload; //for search returns\n\nvar rawaddy = depositaddress.substring(4); //Trim first 4 digits\n\nvar a1 = rawaddy.substr(0,4); // keep next 4 digits\nvar z1 = rawaddy.substring(rawaddy.length - 4); //keep last 4 digits\n\nvar bg = rawaddy.substr(0,1);\nvar bgImg = \"https://raw.githubusercontent.com/cryptocracy/deruptars/main/bg/\" + bg + \"_bg.png\";\n\nvar skin = rawaddy.substr(1,1);\nvar skinImg = \"https://raw.githubusercontent.com/cryptocracy/deruptars/main/skin/\" + skin + \"_skin.png\";\n\nvar eyes = rawaddy.substr(2,1);\nvar eyesImg = \"https://raw.githubusercontent.com/cryptocracy/deruptars/main/eyes/\" + eyes + \"_eyes.png\";\n\nvar teeth = rawaddy.substr(3,1);\nvar teethImg = \"https://raw.githubusercontent.com/cryptocracy/deruptars/main/teeth/\" + teeth + \"_teeth.png\";\n\nvar lips = rawaddy.substr(-4).substr(0,1);\nvar lipsImg = \"https://raw.githubusercontent.com/cryptocracy/deruptars/main/lips/\" + lips + \"_lips.png\";\n\nvar hair = rawaddy.substr(-4).substr(1,1);            \nvar hairImg = \"https://raw.githubusercontent.com/cryptocracy/deruptars/main/hair/\" + hair + \"_hair.png\";\n\nvar hat = rawaddy.substr(-4).substr(2,1);            \nvar hatImg = \"https://raw.githubusercontent.com/cryptocracy/deruptars/main/hat/\" + hat + \"_hat.png\";\n\nvar chest = rawaddy.substr(-4).substr(3,1);\nvar chestImg = \"https://raw.githubusercontent.com/cryptocracy/deruptars/main/chest/\" + chest + \"_chest.png\";\n\n\nmsg.bg = bg;\nmsg.skin = skin;\nmsg.eyes = eyes;\nmsg.teeth = teeth;\nmsg.lips = lips;\nmsg.hair = hair;\nmsg.hat = hat;\nmsg.chest = chest;\n\nmsg.payload = {bgImg, skinImg, eyesImg, teethImg, lipsImg};//pass along urls\nmsg.deruptar = a1+z1;\nmsg.depositaddress = depositaddress;\n\n\n\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":600,"wires":[["22d69490.c4e4dc"]]},{"id":"8cc812a3.91f38","type":"jimp-image","z":"443abc3f.d3eea4","name":"image composite via payload","data":"payload","dataType":"msg","ret":"img","parameter1":"payload","parameter1Type":"msg","parameter2":"0","parameter2Type":"num","parameter3":"0","parameter3Type":"num","parameter4":"BLEND_DESTINATION_OVER","parameter4Type":"Blend","parameter5":"1","parameter5Type":"num","parameter6":"1","parameter6Type":"num","parameter7":"","parameter7Type":"msg","parameter8":"","parameter8Type":"msg","sendProperty":"payload","sendPropertyType":"msg","parameterCount":0,"jimpFunction":"","x":840,"y":600,"wires":[["f9fcf7d1.7db908"]]},{"id":"22d69490.c4e4dc","type":"split","z":"443abc3f.d3eea4","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":630,"y":600,"wires":[["6832165c.47f3c8","8cc812a3.91f38"]]},{"id":"6832165c.47f3c8","type":"debug","z":"443abc3f.d3eea4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":790,"y":560,"wires":[]},{"id":"f9fcf7d1.7db908","type":"image viewer","z":"443abc3f.d3eea4","name":"","width":"284","data":"payload","dataType":"msg","active":true,"x":1050,"y":600,"wires":[[]]}]

It doesn't look like you chose a function in the image node......

I know that, I left it omitted because when i choose composite it doesn't do anything, no error nor preview.

You need to install node-red-contrib-image-tools (I thought you would realise that from the title in the linked topic, sorry)

I did install it, per palette manager.
Your flow was what throws the error.
because its function node has a custom require that references a missing module.

Sorry if i wasn't clear, but when i said i was getting missing module error it was only upon trying to deploy a copy of your flow from link provided (to try to learn from), since it errored I was forced to guess on how to use these node(s)

As ok. I don't remember. I'll check it out when I'm at a computer.

Anyhow regardless of that example, have a look in the examples provided - one of them does image compositing.

To load an example flow, press CTRL+I > examples > node-red-contrib-image-tools

hmmm good to know about those samples to try to learn from, but not seeing any composite examples so I guess I'll keep hacking away until something sticks :stuck_out_tongue:

These nodes seem super impressive though, hopefully this gets me over the hump :smiley:

So ya ... I must be dumb LUL

Cuz I still don't get how this composite function is supposed to work.

When you got a spare moment i'd appreciate further info.

Image Manipulation - Working with multiple images and demonstrating Blit function

Did you try the example named "Image manipulation", pretty sure that uses composite or blit functions

Also search the forum for node-red-contrib-image-tools I've demonstrated this a few times (I think)

blit = composite?

image
none of these have composite selected for their function

Blit is to simply place pixels over the top (replacing the underneath pixels) its faster.

But that flow demonstrates merging images. You can use it as a basis.

hmmm ok i think I was getting tied up cuz I was trying to literally find a sample for the composite function.

hmmm so something still ain't jiving lul