I want to overlay multiple PNG images of different sizes on a transparent canvas using ImageMagick. First I create a transparent canvas of some fixed size, say like
convert -size 1500x1000 canvas:transparent PNG32:canvas.png
Then I loop over my images in order to add each image to the canvas
convert canvas.png nthimage.png -gravity Center -geometry xResxYres xcoord ycoord -composite canvas.png
This works fine, but I may overlay as many as 10 pictures and I do this for thousands of n-tuples of images, so a faster solution would be appreciated. So my question: Can I also do this in one step instead of creating the canvas first and then adding a single image at a time?
Edit: I use ImageMagick 7.0.11-13 on macOS 10.15.7. I run ImageMagick from within a python script, so a file containing a list of input files can be generated if needed. For concreteness, say my input files are file_1.png
up to file_n.png
with sizes A1xB1
up to AnxBn
and should be placed at coordinates X1 Y1
up to Xn Yn
with respect to the center of the canvas and the output file is output.png and should have size 1500x1000.
CodePudding user response:
I really wouldn't recommend shelling out subprocesses from Python to call ImageMagick thousands of times. You'll just end up including too much process creation overhead per image, which is pointless if you are already running Python which can do the image processing "in house".
I would suggest you use PIL, or OpenCV directly from Python, and as your Mac is certainly multi-core, I would suggest you use multi-processing too since the task of doing thousands of images is trivially parallelisable.
As you haven't really given any indication of what your tuples actually look like, nor how to determine the output filename, I can only point you to methods 7 & 8 in this answer.
Your processing function for each image will want to create a new transparent image then open and paste other images with:
from PIL import Image
canvas = Image.new('RGBA', SOMETHING)
for overlay in overlays:
im = Image.open(overlay)
canvas.paste(im, (SOMEWHERE))
canvas.save(something)
Documentation here.