Misalignment of a position after resizing an image with ImageMagick - imagemagick

I want to resize several images and overlay them on a background image by using Imagemagick.
I wrote following code.
convert -size 500x1000 xc:white \
-page +100+200 \( aaa.jpg -resize 50x \) \
-page +200+300 \( bbb.jpg -resize 50x \) \
..............
-layers flatten flatten_img.jpg"
I wanted to put the "aaa.jpg" on (100,200),
and the "bbb.jpg" on (200,300),
but the position of them were misaligned.
For example, the "aaa.jpg" was positioned on (33,66).
If I didn't resize them before doing "-page",
that is,
convert -size 500x1000 xc:white \
-page +100+200 aaa.jpg \
-page +200+300 bbb.jpg \
......
-layers flatten flatten_img.jpg"
the position of them were right.
How Can I put them in the right places ?
Thank you in advance.

I can solve the problem.
convert -size 500x1000 xc:white \
\( aaa.jpg -resize 50x50 -repage +50+100 \) \
\( bbb.jpg -resize 100x100 -repage +100+200 \) \
-layers flatten final.jpg

Related

9-slice scaling with imagemagick?

Given an input image of dimensions 120x120 pixels,
I'd like to use imagemagick to perform
9-slice scaling.
keep the image within the box bounded by
top-left coordinate (10,10)
and bottom right coordinate (110,110) unscaled,
This centre section is 100x100 pixels.
The left side scale by a given factor,
say 3, so this would go from 10x100 pixels to 30x100 pixels
The right side scale by a given factor,
say 2, so this would go from 10x100 pixels to 20x100 pixels
The top and bottom side both scale by a given factor,
say 1.5, so these would go from 100x10 to 100x15 each.
The four corners would scale to fit the new dimensions of the new top, right, bottom, and left sides.
Something similar to
(except in my case the centre element, "5", doesn't need to change)
How can I perform this operation using imagemagick?
(Suggestions for any other CLI tool available on Linux also welcome!)
Using ImageMagick you can approach this as a series of isolated cropping and resizing operations. Here's an example command...
magick input.png -write mpr:img0 +delete ^
( mpr:img0 -gravity west -crop 10x+0+0 -resize 300x100% ) ^
( mpr:img0 -shave 10x0 ) ^
( mpr:img0 -gravity east -crop 10x+0+0 -resize 200x100% ) ^
+append +repage -write mpr:img0 +delete ^
( mpr:img0 -gravity north -crop x10+0+0 -resize 100x150% ) ^
( mpr:img0 -shave 0x10 ) ^
( mpr:img0 -gravity south -crop x10+0+0 -resize 100x150% ) ^
-append +repage result.png
This command will take a 10 pixel wide strip from the left and right sides, widen the left by 300% and the right by 200%, and re-append them to the center.
Then it follows by taking a 10 pixel high strip from the top and bottom, resizing both their heights to 150%, and re-appending them to the center section.
The corners get properly scaled because they go through both the horizontal and vertical resizing operations.
The command uses IMv7 in Windows CLI syntax. For a Windows BAT script you need to double the percent signs "%%".
To make it work on a *nix system change the continued-line carets "^" to backslashes "\" and escape the parentheses with backslashes "\(...\)".
To use it with IMv6 change "magick" to "convert".
Here is one way to do that in ImageMagick 6 (Unix syntax).
Input:
convert logo.png -write mpr:img +delete \
\( \
\( mpr:img -gravity northwest -crop 10x10+0+0 +repage -resize 300x150%! \) \
\( mpr:img -gravity north -crop 100x10+0+0 +repage -resize 100x150%! \) \
\( mpr:img -gravity northeast -crop 10x10+0+0 +repage -resize 200x150%! \) \
+append \
\) \
\( \
\( mpr:img -gravity west -crop 10x100+0+0 +repage -resize 300x100%! \) \
\( mpr:img -gravity center -crop 100x100+0+0 +repage \) \
\( mpr:img -gravity east -crop 10x100+0+0 +repage -resize 200x100%! \) \
+append \
\) \
\( \
\( mpr:img -gravity southwest -crop 10x10+0+0 +repage -resize 300x150%! \) \
\( mpr:img -gravity south -crop 100x10+0+0 +repage -resize 100x150%! \) \
\( mpr:img -gravity southeast -crop 10x10+0+0 +repage -resize 200x150%! \) \
+append \
\) \
-append \
logo_result.png
Result:
If using ImageMagick 7, then change convert to magick.
If on Windows, change the line endings \ to ^ and remove the \ from the ( and ). If in .bat file, double the % to %%.

How to append a same image to multiple images using imagemagick

Hello I want to add a same image to the left side of multiple images. First image is a legend and it common for all the 6 images which I later want to montage 3x2.
I tried this command below before montaging and it did not work. I wanted to see if I could make it work without adding a for loop, which slows down the code.
convert +append image_3_1.png image_1_[1-6].png -geometry +10+0 test.png
I want the image_3_1 added to all the 6 images starting with image_1. Any ideas?
Your question is unclear about:
what your input and expected output images look like or how big they are,
whether you actually need the intermediate images or just the montage,
what the actual issue is with for loops
So here are some ideas...
Option 1
This one avoids for loops and multiple invocations of magick by using a single magick and loading the side image just once and cloning it in memory:
magick side.png \
\( +clone image_1.png +append -write out_1.png +delete \) \
\( +clone image_2.png +append -write out_2.png +delete \) \
\( +clone image_3.png +append -write out_3.png +delete \) \
\( +clone image_4.png +append -write out_4.png +delete \) \
\( +clone image_5.png +append -write out_5.png +delete \) \
image_6.png +append out_6.png
It produces 6 output files as follows:
Option 2
This one avoids for loops by running 6 copies of magick in parallel:
magick side.png image_1.png +append out_1.png &
magick side.png image_2.png +append out_2.png &
magick side.png image_3.png +append out_3.png &
magick side.png image_4.png +append out_4.png &
magick side.png image_5.png +append out_5.png &
magick side.png image_6.png +append out_6.png &
wait
It produces the same 6 output files as above.
Option 3
This does the same by using GNU Parallel to do it more succinctly:
parallel magick side.png image_{}.png +append out_{}.png ::: {1..6}
Option 4
If you don't need the intermediate files, and just want the montage:
parallel -k magick side.png {} +append ppm:- ::: image_*png | magick montage -tile 2x3 -geometry +5+5 ppm:- montage.png
Option 5
This is much the same, avoiding producing the intermediate output files, and also avoiding using GNU Parallel:
magick side.png \
\( +clone image_1.png +append -write ppm:- +delete \) \
\( +clone image_2.png +append -write ppm:- +delete \) \
\( +clone image_3.png +append -write ppm:- +delete \) \
\( +clone image_4.png +append -write ppm:- +delete \) \
\( +clone image_5.png +append -write ppm:- +delete \) \
image_6.png +append ppm:- | magick montage -background black -geometry +5+10 -tile 2x3 ppm:- montage.png
Option 6
This one uses no for loops, a single process, no separate montage command and generates no intermediate files:
magick side.png -write MPR:side +delete \
\( MPR:side image_1.png MPR:side image_2.png +append \) \
\( MPR:side image_3.png MPR:side image_4.png +append \) \
\( MPR:side image_5.png MPR:side image_6.png +append \) \
-append montage.png
Replace the +append and -append with -smush for more layout and inter-image spacing flexibility.
Option 7
Maybe something like this with -smush:
magick side.png -write MPR:side +delete -background cyan \
\( MPR:side image_1.png MPR:side image_2.png +smush 10 \) \
\( MPR:side image_3.png MPR:side image_4.png +smush 10 \) \
\( MPR:side image_5.png MPR:side image_6.png +smush 10 \) \
-smush 30 montage.png
My guess is that option 6 would be the fastest on most machines in most circumstances, if it is flexible enough for you. If you need more flexibility, go with option 7 or 5.
Keywords: ImageMagick, image processing, montage, layout, parallel, smush.

How to create watermark like shutterstock with imagemagick

I want to create image watermark like Shutterstock. I have tried but not able to replicate it. I tried with the following command. The issue is for me is i not able to add diagonal random text to image as Shutterstock does. I have tried many options with no luck.
infile="zoom.jpg"
ww=$(convert -ping "$infile" -format "%[fx:w-1]" info:)
hh=$(convert -ping "$infile" -format "%[fx:h-1]" info:)
convert "$infile" \
-fill "graya(100%,0.75)" \
-draw "line 0,0 $ww,$hh line $ww,0 0,$hh" -alpha off \
-fill "graya(50%,0.25)" \
tile_aqua_500_text_x_text.jpg
composite -dissolve 35 -gravity center logo.png tile_aqua_500_text_x_text.jpg tile_aqua_500_text_x_text.jpg
convert -background none -size 220x320 xc:none -font DejaVu-Sans-Bold -pointsize 30 \
-gravity North -draw "rotate -22 fill grey text 20,10 'knot9'" \
-gravity West -draw "rotate -27 fill grey text 5,15 '89898989'" \
miff:- |\
composite -dissolve 70 -tile - tile_aqua_500_text_x_text.jpg tile_aqua_500_text_x_text.jpg
width=`identify -format %w tile_aqua_500_text_x_text.jpg`; \
convert -background '#0008' -fill white -gravity center -size ${width}x30 -pointsize 10 -font DejaVu-Sans-Bold\
caption:"\nThis image is Copyrighted by Knot9 \n www.knot9.com | Image Id: 89898989\n" \
tile_aqua_500_text_x_text.jpg +swap -gravity south -composite tile_aqua_500_text_x_text.jpg
My Output is
Requirement is
In ImageMagick, you can do the following. Create a small text image on a transparent background using label:. Rotate it. Pad it to control the spacing. Tile it out to fill the image. Then composite the tiled out image over your background image.
Image:
convert lena.png \
\( -size 100x -background none -fill white -gravity center \
label:"watermark" -trim -rotate -30 \
-bordercolor none -border 10 \
-write mpr:wm +delete \
+clone -fill mpr:wm -draw 'color 0,0 reset' \) \
-compose over -composite \
lena_watermark.png
If using ImageMagick 7, then change convert to magick
See https://imagemagick.org/Usage/canvas/#tile_memory for tiling

How to use the first image sequence in a multiple cropping process in ImageMagick

I want resize, crop and concatenate really many images.
I don't want to write the intermediate results to disk, just the final result only.
My script is :
montage -mode concatenate \
\( test.jpg -thumbnail "150x100>" -background white -gravity center -extent 150x100 -page 150x100+0+0 \) \
\( -clone 0 -crop 23x16+80+0 -background white -extent 23x16 \) \
\( -clone 0 -crop 23x16+16+87 -background white -extent 23x16 \) \
...
-delete 0 -quality 100% thumb.jpg
I got always the following error:
montage.im6: geometry does not contain image `test.jpg' # warning/transform.c/CropImage/574.
I tried to use the "repage" and "page" parameters, but I was unsuccessful with them.
Any idea?
Update
Mark asked for examples. So I try to write down the different steps which I would like to merge in one single step:
convert logo: test.jpg
convert test.jpg -thumbnail "150x100>" -background white -gravity center -extent 150x100 -page 150x100+0+0 test.resized.jpg
montage -mode concatenate test.resized.jpg \
\( -clone 0 -crop 23x16+80+20 -background white -extent 23x16 \) \
\( -clone 0 -crop 23x16+92+74 -background white -extent 23x16 \) \
\( -clone 0 -crop 23x16+100+80 -background white -extent 23x16 \) \
-delete 0 -quality 100% result.thumb.jpg
And the results:
you can see here the expected result.
http://phspring.nl/stackoverflow28101334.jpg
I must admit this one has me mystified! I cannot get it to work how you tried, or how I would want to do it at all. I found that I can only make it work if I add a +repage but if I do that it forgets the -extent, so I keep ending up with 2 commands. I also find that +clone refuses to work in place of -clone 0 for this example, which also mystifies me.
The only way I can make it work, and avoid the intermediate file is to stream the output of the first convert to the second one.
convert logo: -resize "150x100>" -background white -gravity center -extent 150x100 JPG:- | \
convert JPG:- \
\( -clone 0 -crop 23x16+80+20 \) \
\( -clone 0 -crop 23x16+92+74 \) \
\( -clone 0 -crop 23x16+100+80 \) \
-delete 0 +append out.jpg

Single command to create multiple file formats from single source file with ImageMagick

I'd like to render a single file say 1.jpg to multiple Read/Write formats ImageMagick supports for eg. 1.png, 1.tif, 1.pdf etc. on a Windows machine. Is there a quick command to do that or do I have to run convert each time to render 1.jpg to each new output format I want?
Like this:
convert 1.jpg \
\( +clone -write 1.gif +delete \) \
\( +clone -write 1.png +delete \) \
1.tif
To make it create only one copy of GIF, PNG and other written files, use this command (asumuing, you want to convert myinputfile.jpg):
name=myinputfile
convert \
${name}.jpg \
-resize 50% \
\( +write ${name}.png \) \
\( +write ${name}.ppm \) \
\( +write ${name}.tif \) \
\( +write ${name}.gif \) \
\( +write ${name}.pdf \) \
${name}.pnm

Resources