Pad image to fit a given aspect ratio

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
mki

Pad image to fit a given aspect ratio

Post by mki »

Hello!

I have pictures of different sizes.
Now I would like to modify the pictures such that in the end all have the same given aspect ratio.
The aspect ratio should not be reached by stretching or cropping, but by padding.

For example:
A Picture in the format 100 x 100 should be transformed to an aspect ratio of 1:2
So the resulting picture should be the format 100 x 200, containing the original picture in the coordinates [1..100] x [51..150].
The 100 x 50 rectangles added at the bottom and the top of the original picture should be filled with the background colour.

Is it possible to do such a transformation with imagemagick?

Thanks!
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Pad image to fit a given aspect ratio

Post by fmw42 »

convert image -gravity center -background white -extent 100x200% result

see http://www.imagemagick.org/Usage/crop/#extent
mki

Re: Pad image to fit a given aspect ratio

Post by mki »

Thanks for your answer.

that's not exactly what I need, because I don't want to give the absolute size of the picture, but only the aspect ratio.
So for example if I give the aspect ratio 1:2, the following should happen depending on the input graphic:

* applied to a 100x100 picture: -> 100x200
* applied to 100x200 -> 100x200 (unchanged)
* applied to 200x100 -> 200x400

Is this possible?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Pad image to fit a given aspect ratio

Post by fmw42 »

My conversion was in percent, so that is simply 100 x aspect ratio of 1:2 = 100x200%

If you want something more sophisticated, then you will have to script the conversion after testing the aspect ratio of the actual image.

Try this

infile="yourimage.jpg"
outfile="yourimage_1to2.jpg"
bgcolor="white"
ww=`convert $infile -ping -format "%w" info:`
hh=`convert $infile -ping -format "%[fx:2*w]" info:`
convert $infile -gravity center -background $bgcolor -extent ${ww}x${hh} $outfile
mki

Re: Pad image to fit a given aspect ratio

Post by mki »

Thank you!

Actually I noticed the %-sign in your original code line, but the command did not give the result I wanted.
The result was the same as without %-sign.

Now I did an update to imagemagick, and your command works as expected.
So it seems that there was a bug in imagemagick 6.5.2-9 which is fixed in 6.5.7-0.


One further question:
I there a fast way to pad an image to the aspect ratio 1:2 if it is in landscape format, and to 2:1 if it is in portrait format?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Pad image to fit a given aspect ratio

Post by fmw42 »

mki wrote:Thank you!

Actually I noticed the %-sign in your original code line, but the command did not give the result I wanted.
The result was the same as without %-sign.

One further question:
I there a fast way to pad an image to the aspect ratio 1:2 if it is in landscape format, and to 2:1 if it is in portrait format?

With and without % worked because your image was 100x100.

No fast way that I know about. The code I gave last can be modified to change according to the actual image aspect ratio (i.e. landscape vs portrait). But you did not ask about that originally. I can try to write that later today, if you need it. IM does not have anything that I know of that pads according to landscape vs portrait. Resizing can use ^ symbol to size according to the smaller dimension. But I know of nothing like that for padding.
mki

Re: Pad image to fit a given aspect ratio

Post by mki »

EDIT:
I guess now I know how the -extent argument with the percentage sign works.
Writing -extent 100x200% means that the image height is doubled by padding, no matter what the original aspect ratio was.


Btw, 100x100 was only an example to show what I want.

In fact I have a big photo collection consisting of photos of different sizes and aspect ratios (3:4 and 2:3), and I want to bring them all to 2:3.

And the photos are mixed landscape / portrait formats, thus my new question...
mki

Re: Pad image to fit a given aspect ratio

Post by mki »

Ok, now everything is clearer.
I got something totally wrong, and I guess there is no bug in the older imagemagick version.

Thanks for you script.
It works in all the example cases I listed in my first post.

But I guess it does not work in the case that not the height, but the width has to be increased to reach the given aspect ratio.

That would be in the original example:
* applied to a 100x400 picture: -> 200x400
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Pad image to fit a given aspect ratio

Post by fmw42 »

Yes, the last case is not covered. There are going to be many special cases.

I am working on a script now and it should available in a day or so.
Last edited by fmw42 on 2009-11-30T18:06:31-07:00, edited 2 times in total.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Pad image to fit a given aspect ratio

Post by anthony »

The only suggestion I have is DIY it. However IM can do the mathematics for you, by using a viewport NO-OP distortion.

That is use -set option:distort:viewport whcih can take %[fx:...] mathematical calculations to work out the right size and offset for a specific aspect ratio. Then
run the image though -distort SRT 0.

An exampl of this type of math was given in
http://www.imagemagick.org/Usage/distor ... red_square
but this was for cropping the largest centered square, not for aspect ratio padding.
however while the math is different the command layout is the same.

NOTE for any aspect ratio their is TWO solutions (just as their is for centered square). One where the image is extended in width, and one where it is extended in height. This depends in the input images current aspect ratio.

Now if someone like to work out the math. I can add it to IM examples.

WARNING: I go on vacation for 3 months in two days, so get the solution in fast!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Pad image to fit a given aspect ratio

Post by fmw42 »

I now have a script, aspectpad, to do this. Get it at my web site below.
mki

Re: Pad image to fit a given aspect ratio

Post by mki »

@fmw42:
Thank you so much for this great script and the documentation!!

I just used it to prepare digital photos for the printing service.
The rules of the printing service are that you have to select one aspect ratio, 2:3 or 3:4 which applies to all photos within a single order. If the aspect ratio of a certain photo differs from the selected one, it will be cropped.

And that is not what I want. So now I use your 'aspectpad' script to pad the photos to the desired aspect ratio.

When preparing the photos, a small enhancement came to my mind which might be useful:
Assume that I select the aspect ratio 2:3 for the order.
If a photo is in aspect ratio 3:4, it should be padded, no question.
But if the aspect ratio of the photo is already close to 2:3, it would be better not to pad the photo and let the printing service do the cropping (cropping doesn't do much harm here, but padding would introduce quite noticable thin white lines at two edges, which do not look too good).

So it would be nice to have an additional argument <tolerance>, which is a float >= 1.
If the aspect ratio (possibly after a portrait/landscape matching) of an image differs from the parameter <aspect> by a factor less than <tolerance>, it should not be changed. Otherwise, proceed as before.
A good default value for <tolerance> is 1.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Pad image to fit a given aspect ratio

Post by fmw42 »

Don't you mean that you want the difference in desired and actual aspect ratios to be close to zero? I would set it up to be tolerance default=0 (no pad if exactly the right aspect already, which is what it is doing now). But then you can set the tolerance to be whatever value you find useful.

Alternately, I can use the ratio of the two aspects. That would be tolerance of 1 for a perfect match. Might that be what you are thinking.

By the way, you may also want to look at my aspect script that resizes and either crops or pads to make an image fit a given size.
mki

Re: Pad image to fit a given aspect ratio

Post by mki »

Yes, I thought about the ratio (because of that I used the word factor and not summand), so the default value of 1 would just give the current behaviour without a <tolerance> parameter.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Pad image to fit a given aspect ratio

Post by fmw42 »

mki wrote:Yes, I thought about the ratio (because of that I used the word factor and not summand), so the default value of 1 would just give the current behaviour without a <tolerance> parameter.
What do you want to happen if the image aspect is too close to the desired aspect? Do you want the script to copy the input to the output or just bail and not process the input? If the latter, do you want a terminal message to that effect?
Post Reply