Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert one image into another using convert

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?

like image 923
Yimin Rong Avatar asked Jul 20 '16 09:07

Yimin Rong


People also ask

How do you insert a picture in a picture?

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.

What is the use of ImageMagick?

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.

What is ImageMagick Ubuntu?

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.


1 Answers

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

enter image description here

enter image description here

enter image description here

like image 96
Mark Setchell Avatar answered Sep 24 '22 20:09

Mark Setchell