ImageMagick: Layering Images with convert -composite with gravity center - image-processing

background
overlay
composite -gravity center overlay.png background.jpg result1.jpg
result1.jpg
convert -composite background.jpg overlay.png -gravity center result2.jpg
result2.jpg
convert -composite background.jpg -gravity center tool_marker.png result3.jpg
result3.jpg
How can I achieve the results from result1 while using convert as the executable rather than composite?
Thanks!

You can start by using the operators in the right order. That is set the 'settings' first.
"Composite" command is 'read all settings then apply ONE operation, type of command (traditional UNIX)
"Convert" is a 'do options as you see them', with MULTIPLE operations possible. (script-like command)
convert background.jpg tool_marker.png -geometry +50+50 -composite result4.jpg
Note the +50+50 is the location of the top-left corner of the 'tool_marker.png" image. You will need to subtract the 'pin-point' location in that image to get it to pin point in the right location.
Gravity Center (if given BEFORE the -composite operation that uses it), aligns the center of BOTH images.
convert background.jpg tool_marker.png -gravity center -composite result4.jpg

Related

How to resize overlay image by ratio and with relative position it from the right?

Let's start with a background and an overlay image:
magick convert -size 500x500! xc:red background.jpg # make a big red background
magick convert -size 100x100! xc:blue overlay.jpg # make a smaller blue overlay
To composite from right side I can use
$geom=magick convert overlay.jpg -print "+%[fx:w+50]+0" null:
magick convert background.jpg overlay.jpg -gravity northeast -geometry $geom -composite output.jpg
However, in my real project, I need to run this with various background images, whose sizes are also various. I would like the overlay to use relative size to the background instead of absolute size.
To overlaying a watermark/logo with relative dimentions, I can use:
magick background.jpg overlay.jpg -resize %[fx:t?u.w*0.9:u.w]x%[fx:t?u.h*0.9:u.h] -gravity northease -composite output.jpg
To resize overlay image by ratio and with relative position it from the right, I try:
magick background.jpg overlay.jpg -resize %[fx:t?u.w*0.1:u.w]x%[fx:t?u.h*0.1:u.h] -gravity northeast -geometry +[fx:t?u.w*0.1:u.w]+[fx:t?u.h*0.1:u.h] -composite output.jpg
But it says:
magick.exe: invalid argument for option '-geometry' '+[fx:t?u.w*0.1:u.w]+[fx:t?u.h*0.1:u.h]' at CLI arg 7 # error/operation.c/CLISimpleOperatorImage/2522.
The documentation for geometry doesn't seem to talk about this. Do you know why?
I'm using v7 on Windows
I miss the %. Correct code:
magick .\base.jpg .\logo.png -resize %[fx:t?u.w*0.1:u.w]x%[fx:t?u.h*0.1:u.h] -gravity northeast -geometry +%[fx:t?u.w*0.03:u.w]+%[fx:t?u.w*0.03:u.w] -composite output.png
See Format and Print Image Properties
The reasoning behind the %[fx:t?u.w*0.9:u.w]
From The FX Special Effects Image Operator:
u: first image in list
v: second image in list
t: index of current image (s) in list
w: width of this image
So in plain language, it means that if the image in question is the second image, whose index is one, of which the ternary conditional operator also read as true, then resize it to 90% width of the first image, else do no resize. Or else -resize option will apply to each images in an image sequence (i.e. all input images before it, but not after it).

Position another image relatively to text with ImageMagick

convert inputImage.jpeg -gravity South -size x32 label:"Morning in paradise" -geometry +0+40 -composite starImage.png -composite finalImage.png
With this command, I can add text at the bottom of inputImage and another image on this text. But how can I set (or prefix) the starImage image to the left of the text that has a dynamic width and fixed height. I have attached some images below to explain what I want to do.
Obtained result
Expected result
You can read the star image, create the text label, and append them together inside parentheses. Then composite that assembled star-text image over the main input image. A command like this should get pretty near what you described.
convert inputImage.jpeg -gravity center -size x32 \
\( starImage.png label:"Morning in paradise" +append \) \
-geometry +0+40 -gravity South -composite finalImage.png
If you want a star on both sides of the line of text, you can read the "starImage.png" in once more after creating the label and before appending.
I think what you should do using Imagemagick is to set the width you want for the text so that there is room for the star image to be append on each side and have some padding as well. Here is how I would do it. Since you did not provide your input or star image, I have simulated the image as a blue image and taken some graphic image that I had around to simulate your star or logo. I first measure the desired width. The width is 70% of the difference is width between the large blue image and twice the width of the logo. I append the logo on each side of the text image, then composite that near the bottom of the blue image to create your final image. If this were in Imagemagick 7, it could be done in one command. This is Unix syntax.
Image:
Logo:
width=`convert background.jpg logo.png -format "%[fx:0.70*(u.w-2*v.w)]\n" info: | head -n1`
convert background.jpg \
\( logo.png \
-size ${width}x -background none -fill black -font Arial -gravity center label:"THIS IS A TEST" \
logo.png \
+append \) \
-gravity south -geometry +0+50 \
-compose over -composite \
result.jpg

Practical Imagemagick stack (combined) complex commands

I want a combined command that can perform the following task in single execution. I searched the internet, but hardly found any tutorial that guide us to write any stack command. I can found single command for each operation, such as -composite, -blur, etc, and I know I can pipe the command as such
convert ... mpr:- | convert ... mpr:- | ... | convert ... png:-
However, I want a combined command that use \( ... \) and mpr:{label} since this will increase the performance as all operations are executed in single process (pipeline in shell can degrade the performance, and the process sequence is required to be in order).
The process sequence as such:
put flower.png on top of the frame.png -> mpr:framedFlower
put mpr:framedFlower on top of the background.png -> mpr:out2
blur the heart.png, right-gradient-transparent the smiley.png and put both image on top of mpr:out2 -> mpr:out3
annotate the mpr:out3 with "Hello world" (placement=bottom) -> png:-
I don't include the commands that I have tried because they are too messy and it will be an insult to those users who read it. I tried for many hours, but can't get it done. Please advise.
I haven't spent ages futzing with the exact coordinates as I am only using sample pictures, but this one-liner contains every technique you need to do what you are asking.
There is basically one line of code per element in the final image:
convert frame.png -resize 500x400\! \( flower.png -resize 400x300\! \) -gravity center -composite \
background.png +swap -gravity northwest -geometry +100+150 -composite \
\( heart.png -resize 200x200 -blur 0x8 \) -geometry +1200+250 -composite \
-gravity south -pointsize 72 -fill red -annotate +0+60 'Hello world' \
\( emoji.png -resize 250x250 -channel a -fx "u.a*(1-(i/w))" \) -gravity northwest -geometry +1200+500 -composite result.png
The first line reads in the picture frame and the flower and resizes them each independently because of the parentheses and then composites the flower into the frame.
The next line loads the background and then uses +swap to put it behind the framed picture from the previous line. It then sets -gravity to northwest as the origin for the ensuing -geometry before compositing the framed picture onto the background.
The next line loads the heart and resizes and blurs just the heart before compositing that onto the main picture at your specified position.
Next up is the annotation - the only interesting thing is that I set the -geometry to south which means that the offsets to -annotate are relative to the bottom centre of the background.
Finally, I load the emoji-thing and resize just it in parentheses before compositing over the main image. The only interesting thing is that I use -fx to alter the alpha channel (-channel a) and I multiply the existing transparency (u.a) by the fraction of the inverse of the distance we are across the image, namely (1-(i/w)).
Hope that is fairly clear!
Start Images

Imagemagick: distorting images on top of background?

I've got one background image: sky.jpg
And two transparent PNG images: gradient.png and tree.png
Now I want to draw the two images on the background with a perspective distortion, like this:
The destination coordinates of the two images are, in clockwise order (starting top left) :
gradient: 62,129 421,218 383,458 147,548
tree: 445,100 765,47 698,368 529,396
I cannot figure out how to start with one image (in this case the sky background) and then take another image and draw that with perspective distortion to specific destination coords within the background. Also doing this with more than one image at a time, within one convert command, troubles me.
For example, when I start with just one image (the gradient) and try this:
convert sky.jpg \( gradient.png -alpha set -virtual-pixel transparent \
+distort Perspective "0,0 62,129 255,0 421,218 255,255 383,458 0,255 147,548" \) \
-compose src-over -composite result.jpg
It gets correctly warped (so the coordinates are relatively correct) but it's drawn in the top left corner, not at the coordinates I specify.
Also I'm a bit unsure if my usage of -compose and -composite is correct (I took this from various IM manual examples).
One other thing that is unclear to me: in case of the 256x256 image, should I use 255,0 and 255,255 and 0,255 as the corner coordinates, or 256,0 and 256,256 and 0,256 ?
Any IM experts who can shed light on these issues?
Add a -geometry just before the -composite like this:
convert -size 800x600 xc:black \( -size 300x200 xc:red \) -geometry +90+10 -composite result.png

how do i place a 4 * 6 image on a letter page at the top

I am using imagemagick to convert files and reposition them, i have a 4 * 6 png which i need to position on a letter canvas on the top half of the page.
I have the below command which i am using, but its confusing. can anyone suggest how i can achieve what i want.
this is what i have tried, can any one guide me on this.
convert -rotate -270 -page Letter me-9370120111400937899958.png on-9370120111400937899958.pdf
I have also tried this, but the overlayed image is not moving and is stuck to the bottom
%x{convert -page Letter -rotate -270 "/var/folders/rp/rk2q4l7j4ds_w37vwvgx46tr0000gn/T/a8.png" -geometry +50+50 "/var/folders/rp/rk2q4l7j4ds_w37vwvgx46tr0000gn/T/a8.pdf"}
I have tried reading on this link http://www.imagemagick.org/script/command-line-processing.php#geometry but could not figure out.
Updated Answer
It occurred to me later that you may have meant this:
convert -page letter -gravity north \( a.jpg -background yellow -splice 0x10 \) a.pdf
Obviously change yellow to none and increase the 0x10 to 0x20 to move further down the page, and add -rotate 90 before the splice maybe.
Original Answer
Not sure exactly what you mean, but I think this will get you started. Let's try some options. I will make the canvas yellow so you can see it and the file you want to position on top will be red.
So let's try some options...
First, let's move the image across to the right by zero pixels and down from the top-left by 40 pixels - the default position (or gravity) is NorthWest so we are positioning relative to that.
convert -size 612x792 xc:yellow a.jpg -geometry +0+40 -composite result.jpg
If you want the image centred, use -gravity north and position relative to that - a little closer to the edge this time maybe:
convert -size 612x792 xc:yellow -gravity north a.jpg -geometry +0+10 -composite result.jpg
If you want the background rotated:
convert -size 792x612 xc:yellow -gravity north a.jpg -geometry +0+40 -composite result.jpg
If you want just the overlay rotated, do that in "aside processing":
convert -size 612x792 xc:yellow -gravity north \( a.jpg -rotate 90 \) -geometry +0+40 -composite result.jpg
If you want the canvas white, change yellow to white. If you want the canvas transparent, change yellow to none.

Resources