I have one image logo.png
of size 720x720
, I want it to be stretched or squeezed to fit the entire height or width, preserving aspect ratio, centered inside a bounded rectangle top-left: 32,432
and bottom-right: 607,919
in another image background.png
image of size 640x960
.
So for the above example, logo.png
would be resized to 488x488
and positioned at top-left: 76,432
.
But I don't want to have to calculate 488x488
or 76,432
, just want to use the top-left
and bottom-right
specifiers above, i.e. let ImageMagick figure it out.
Can ImageMagick do something like this? If it can't on its own, is there a scripting solution using convert
and anything else?
Use the file browser to locate the photo that you want to add to the existing image. Select it and then click Place. This will add your new image to the background, which was the photo you already had open. Use the dragging points at the edge centers and corners to resize the image; drag it to move it around.
ImageMagick, invoked from the command line as magick , is a free and open-source cross-platform software suite for displaying, creating, converting, modifying, and editing raster images. Created in 1987 by John Cristy, it can read and write over 200 image file formats.
ImageMagick is a software suite which can be used to create, edit and display bitmap images, either from the command line or using a graphical interface. It can read, convert and write images in a large variety of formats.
Hopefully Even Simpler Version
I think this still produces the same result but is simpler:
#!/bin/bash
# Make initial images
convert -size 720x720! gradient:red-yellow -fill white -gravity center -pointsize 72 -annotate 0 "logo" logo.png
convert -size 640x960! gradient:blue-cyan -fill white -gravity north -pointsize 72 -annotate 0 "background" background.png
# Specify top-left and bottom-right
tl="32,432"
br="607,919"
# Get x1,y1,x2,y2 - bounding box of inserted image
IFS=, read -r x1 y1 <<< "$tl"
IFS=, read -r x2 y2 <<< "$br"
# Work out width and height
w=$((x2-x1+1))
h=$((y2-y1+1))
# Resize logo proportionally, then extend canvas with invisible pixels to full size of insertion area and composite onto background
convert background.png \( logo.png -resize ${w}x${h} -background none -gravity center -extent ${w}x${h} \) -gravity northwest -geometry +${x1}+${y1} -composite result.png
Improved Answer
This is simpler and faster and hopefully the same result:
#!/bin/bash
# Make initial images
convert -size 720x720! gradient:red-yellow -fill white -gravity center -pointsize 72 -annotate 0 "logo" logo.png
convert -size 640x960! gradient:blue-cyan -fill white -gravity north -pointsize 72 -annotate 0 "background" background.png
# Specify top-left and bottom-right
tl="32,432"
br="607,919"
# Get x1,y1,x2,y2 - bounding box of inserted image
IFS=, read -r x1 y1 <<< "$tl"
IFS=, read -r x2 y2 <<< "$br"
# Work out w and h, and smaller side "s"
w=$((x2-x1+1))
h=$((y2-y1+1))
s=$w
[ $h -lt $w ] && s=$h
echo Smaller side: $s
# Resize logo proportionally, then extend canvas with invisible pixels to full size of insertion area and place on background
convert background.png \( logo.png -resize ${s}x${s} -background none -gravity center -extent ${w}x${h} \) -gravity northwest -geometry +${x1}+${y1} -composite result.png
Original Answer
I think, from your comments that you want the resized image centred, so I have done that.
Also, there is lots of debug code and I have not yet optimised this until I know I am on the right track, so it can definitely be improved.
#!/bin/bash
# Make initial images
convert -size 720x720! gradient:red-yellow -fill white -gravity center -pointsize 72 -annotate 0 "logo" logo.png
convert -size 640x960! gradient:blue-cyan -fill white -gravity north -pointsize 72 -annotate 0 "background" background.png
# Specify top-left and bottom-right
tl="32,432"
br="607,919"
# Get x1,y1,x2,y2 - bounding box of inserted image
IFS=, read -r x1 y1 <<< "$tl"
IFS=, read -r x2 y2 <<< "$br"
# Work out w and h, and smaller side "s"
w=$((x2-x1+1))
h=$((y2-y1+1))
s=$w
[ $h -lt $w ] && s=$h
echo Smaller side: $s
# Work out size of resized image
read -r a b < <(convert logo.png -resize ${s}x${s} -format "%w %h" info:)
echo Resized logo: $a x $b
# Work out top-left "x" and "y"
x=$((x1+((w-a)/2)))
y=$((y1+((h-b)/2)))
echo x:$x, y:$y
convert background.png \( logo.png -resize ${s}x${s} +repage \) -geometry +${x}+${y} -composite result.png
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With