ImageMagick - Overlay one image onto many - imagemagick

I have a folder of images labelled: test.png and img000.png-img480.png
How can I overlay test.png onto every imgxxx.png individually?
Currently "magick test.png img000.png -compose over -composite result.png" works for a single .png, and I'm not sure how/if mogrify can be used for all of them.
Any help is greatly appreciated (non-imagemagick solutions would also be great!) thanks :)

Make a copy of a few test files in a separate directory then change to that directory and try this:
magick mogrify -draw 'image Over 180,100 0,0 test.png' img*png
The 180,100 specifies where it will be drawn, and the 0,0 says to use the current size of test.png, i.e. no resizing. You can change the blend mode (i.e. Over here) for different effects. Get a list of available blend modes with:
magick identify -list compose
If you would like the results written in a different directory called RESULTS, use:
mkdir -p RESULTS
magick mogrify -path RESULTS -draw 'image SrcOver 180,100 0,0 test.png' img*png

Related

How can I specify a background in Imagemagick mogrify based on the colour of an existing pixel?

I want to use mogrify to set the background colour of a large number of images to be whatever colour is at a specific pixel, to make them square.
The vast majority have a single colour in the image background, or are photos in front of a single colour (so with only slight variations from shadows, etc.).
(The specific purpose in this case is to make the images all the same size and square for StyleGAN2-ADA training, so I want to avoid big "letterbox" rectangles where possible as it would be seen by the discriminator as relevant to the image, where a more faded-in background that approximately matches would be more likely to be ignored. Specifically, I have thousands of pictures of single dolls and action figures from various sources, some of which are "trimmed out" to have a truly solid colour background, others of which are against solid colour tables/walls/etc, for instance, from eBay images and such.)
Since they do not all have the same colour in the image background (the colour in the image, as opposed to the 'background colour' setting as per ImageMagick's jargon), I need to sample a pixel and set the background, but I can't figure out how. I tried things based on methods used to set the whole image to one colour, to no avail.
I have tried:
mogrify -verbose -resize 1024x1024 -gravity center -background 'p{10,10}' -extent 1024x1024 -resize 256x256 *.jpg
and
mogrify -verbose -resize 1024x1024 -gravity center -background "%[pixel:p{10,10}]" -extent 1024x1024 -resize 256x256 *.jpg
and neither works. I can't find any other possibilities in the documentation.
EDITED TO ADD: While testing various commands I came across a way to modify your original command to make it work on ImageMagick versions as far back as IMv6.8.
mogrify -resize 1024x1024 -set background "%[pixel:p{10,10}]" \
-gravity center -extent 1024x1024 -resize 256x256 *.jpg
The significant difference is setting the background color in an unusual way. Instead of the normal option -background <color>, this command uses -set background <color>. Then it behaves as expected using that +10+10 color as the background in the "mogrify" command.
For ImageMagick v7 use magick mogrify instead of just mogrify.
The following was my original answer. The suggestion for IMv6 "convert" may be quite useful for some workflows, but the answer above seems to be the simplest, most direct route.
PREVIOUS ANSWER:
ImageMagick v6 won't do that inline parsing of the color, but there are ways to get the same result, usually with IM's "convert" in a "for" loop in your shell. I don't know which shell you're using so I don't know how you'd write a "for" loop, but running this command inside the loop on each image should give you the results you described...
convert $image -resize 1024x1024 ( +clone -crop 1x1+10+10 ) +swap \
-resize 1024x1024 -gravity center -composite -resize 256x256 $image
That reads in the image, resizes it, makes a clone inside the parentheses, and extracts that pixel at +10+10. After the parentheses that single pixel get resized to a 1024x1024 square. Then setting the gravity to "center" and compositing the input image over that colored square gives you the result you described.

Compose multiple regions of an image into a target

I'm trying to use ImageMagick to compose different pieces of a rendered PDF into a target. E.g., I want to have ImageMagick render the PDF at 300dpi, then create a 300x400 pixel output image, then take from the PDF the area 10x20+30+40 and place it in the target (300x400 pixel image) at 12,34. Then take another (and a third and fourth) chunk at different coordinates with different sizes and place them at different places.
I cannot seem to figure out how to do this in one go, and doing it in multiple runs always re-renders the PDF and takes awfully long. Is this even possible?
Here's an idea of how you can approach this. It uses the MPR or "Memory Program Register" that Fred suggested in the comments. It is basically a named chunk of memory that I write into at the start and which I recall later when I need it.
Here is a rather wonderful start image from the Prokudin-Gorskii collection:
The code resizes the image and saves a copy in the MPR. Then, takes a copy of the MPR, crops out a head, resizes it and composites the resized result onto the resized original at a different location and then repeats the process for another head.
magick Prokudin.png -resize 300x400\! -write MPR:orig \
\( MPR:orig -crop 50x50+180+84 -resize 140x140 \) -geometry +10+240 -compose src-over -composite \
\( MPR:orig -crop 40x40+154+184 \) -geometry +40+100 -compose src-over -composite \
result.png
If you have trouble understanding it, try running it with the second or third line omitted so it just does one head ;-)
Hopefully it covers all the aspects of your question and you can adapt it to your PDF.

Imagemagick convert and compose batch of files

I am trying to make a fast convert of a batch of files like this:
convert ./src/*.png -set filename: '%t' -gravity West -draw 'image over 0,0 424,600 "./panel.png"' ./dest/%[filename:].png
which is pretty similar to COMPOSITE:
convert ./src/*.png ./panel.png -set filename: '%t' -gravity +0+0 -composite ./dest/%[filename:].png
except the last one is not working and just making one first crappy-looking file.
Looks like it's bug?
Does anybody know how to make it more correct with -composite?
for|awk|ls|find for each file in shell is not acceptable - because that is slower than the first example.
Read in the list of files,
set their output filenames,
include the IM special image placeholder "null:",
read in your overlay image,
optionally, set the geometry,
and composite that overlay onto all the other images with "-layers composite".
That null: separates the original input file list from the overlay image so ImageMagick knows where in the stack you want to start doing the composite.
Try something like this (one step per line for readability):
convert ./src/*.png \
-set filename: '%t' \
null: \
./panel.png \
-layers composite ./dest/%[filename:].png
You could use Imagemagick mogrify command. See http://www.imagemagick.org/Usage/basics/#mogrify and http://www.imagemagick.org/Usage/basics/#mogrify_compose
cd to input directory
mogrify -format png -path ./dest -gravity West -draw 'image over 0,0 424,600 "./panel.png"' *.png
Looks like it's bug?
Not a bug. Your second command is telling ImageMagick to consume all files matched into an image stack, and composite it as one.
You can attempt the same solution with the mogrify utility, but I believe it would be way simpler if you expand the bash script with a single for loop.
for f in $(ls src/*.png)
do
dest=$(basename $f);
convert "$f" ./panel.png -gravity West -composite "./dest/$dest"
done

How to add a watermark to all images in a folder using ImageMagik

I have been trying to find a way of watermarking all .jpg files in a given folder using ImageMagik directly from the terminal. I have searched a lot and I found the following:
composite -compose atop -gravity southeast -geometry +10+10 wm.png *.jpg
What I want to achieve is to add the watermark(wm.png) right under the bottom-right corner of each image and save the file under the same name. All images are different width but none is wider than 800px. So my watermark image is 800px wide. I want the watermark to be put right under the image, not over it and in the same time being cut to fit the size of the .jpg image.
The problem with the command above is that it s always outputting the following error:
composite: unable to open image `'tm.png'': No such file or directory # blob.c/OpenBlob/2480.
composite: missing an image filename `10.jpg' # composite.c/CompositeImageCommand/1593.
for i in *.jpg
do
composite -gravity southeast -geometry +10+10 wm.png "$i" "wm_$i"
done

ImageMagick: lay a partly transparent tile over an image

I have a wallpaper.jpg (size: 1920x1280) and a partly transparent tile.gif (size: 16x16).
On a website I want to have the tile as a x- and y-repeated overlay over the wallpaper.
Right now, this overlay is realized using CSS. I want to save one request and merge the (repeated) tile.png with the wallpaper.jpg using ImageMagick. The wallpaper.jpg is generated via ImageMagick anyway.
Following the Documentation of the -tile option, I came up with the following command:
convert wallpaper.jpg -size 1920x1280 tile:tile.gif -compose over -composite result.jpg
The result, however, is a 1920x1280 jpg filled with the tile, but no wallpaper shining through. Instead, the transparent part of the tile seem to be white.
The documentation says:
If the tile image is partially transparent then a 'Over' "-compose" method will need to be specified.
So what's wrong?
I also tried -flatten instead of -composite... same result.
edit:
I realize, there is also another -tile option documentation. It seems to follow the concept of overloading. Unfortunately, I cannot figure out how to use it correctly.
This should do the trick:
convert wallpaper.jpg -background none -size 1920x1280 tile:tile.gif -composite result.jpg
(you can also add -compose over, but that should not make any difference).
Not sure if it will help, but have you tried converting your tile.gif to a 24-bit PNG file with Alpha/Transparency? - Scratch that....
I found some example showing but am unsure about the full command line:
composite -tile tile.gif netscape: wallpaper.jpg
Source: http://www.imagemagick.org/Usage/compose/#tile

Resources