1

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.

220284
  • 179
  • 7
  • Sure. Do you have a file with a list of input image names? And output image names? What do a few lines look like? What OS are you running? What IM version are you running? – Mark Setchell Dec 17 '21 at 22:55
  • @MarkSetchell Thanks for getting back to me. I have added some clarification. – 220284 Dec 17 '21 at 23:23
  • I still don't understand your question, sorry. It seems rather vague... what are *"thousands of n-tuples of images"*? Does one n-tuple of images produce one output image? What does one n-tuple of images look like? Where are the X,Y coordinates of where the images must be placed? How are the output filenames determined? – Mark Setchell Dec 19 '21 at 10:58
  • By thousands of n-tuples of images I mean that I want to merge n images a thousand times, so any speed improvement is welcome. Let's perhaps take a concrete example. The canvas is `canvas.png` of size 1500x1000 and I have 3 images `1.png 2.png 3.png` of sizes `300x200 600x400 900x600` and I want to place them at the coordinates `+100-100 +200-200 +300-300` with respect to the center of the canvas. Let's say the output is `output.png`. How would I do this? – 220284 Dec 19 '21 at 11:08
  • 1
    If you have multiple input images to composite, you can use -page +X+Y in place of -geometry and then use -flatten. That way you can composite several images in one command line without multiple -composites. See https://legacy.imagemagick.org/Usage/layers/#flatten – fmw42 Dec 19 '21 at 23:05
  • @fmw42 Thanks! That's what I was looking for. – 220284 Dec 21 '21 at 07:40

1 Answers1

1

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.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Thanks Mark! That's helpful. Unfortunately PIL Is not doing as good a job as IM qualitywise, but it is indeed significantly faster. – 220284 Dec 21 '21 at 07:43
  • Mmmm... I don't understand how that can be. Your input and output images are both lossless PNG files which will be held bit-for-bit identically by both packages and there doesn't appear to be any blending or calculations that could introduce differences so I am at a loss to understand what you are seeing. I'm glad you have a solution though, so good luck with your project. – Mark Setchell Dec 21 '21 at 10:27
  • I now realised that the quality loss is related to some difficulty when all images have an alpha channel. I used the method proposed here https://stackoverflow.com/a/5324782/14130611 But as stated before, this results in quality loss. – 220284 Dec 21 '21 at 16:57