Pad image to fit a given aspect ratio
Pad image to fit a given aspect ratio
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!
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!
- 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
convert image -gravity center -background white -extent 100x200% result
see http://www.imagemagick.org/Usage/crop/#extent
see http://www.imagemagick.org/Usage/crop/#extent
Re: Pad image to fit a given aspect ratio
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?
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?
- 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
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
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
Re: Pad image to fit a given aspect ratio
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?
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?
- 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
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.
Re: Pad image to fit a given aspect ratio
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...
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...
Re: Pad image to fit a given aspect ratio
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
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
- 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
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.
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.
- 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
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!
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/
https://imagemagick.org/Usage/
- 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
I now have a script, aspectpad, to do this. Get it at my web site below.
Re: Pad image to fit a given aspect ratio
@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.
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.
- 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
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.
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.
Re: Pad image to fit a given aspect ratio
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.
- 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
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?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.