Crop to an aspect ratio with "-crop 3:2"

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
User avatar
GeeMack
Posts: 607
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Crop to an aspect ratio with "-crop 3:2"

Post by GeeMack » 2018-01-31T13:02:57-07:00

The announcement about the new mode of cropping to an aspect ratio with "-crop 3:2" looks extremely useful. I have a couple suggestions.

First, I noticed that specifying an aspect with "-extent 3:2" also produces the same sort of proportional cropping. Maybe a flag could be added to instruct "-extent" to create a 3:2 canvas that still contains the entire input image. The area outside the original input could be filled with the background color. The command might look something like this, for example...

Code: Select all

magick logo: -background green -gravity center -extent 3:2^ result.png
Also, although it might be a bit more complicated to code, maybe another flag could be added to instruct the "-crop" or "-extent" operation to follow the W<H or W>H of the input image. In other words, if the input is 400x800 and the operator is "-crop 3:2" the output could be 400x600. And example command could look something like this...

Code: Select all

magick logo: -gravity center -crop 2:3! result.png
Questions about cropping or extent-ing to certain aspect ratios come up frequently in these forums. This quick built-in method for handling that without other FX calculations is a great idea. Thanks for adding it!

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

Re: Crop to an aspect ratio with "-crop 3:2"

Post by fmw42 » 2018-01-31T13:24:04-07:00

GeeMack:

1) Are you asking for a -define or new geometry flag that would crop 3:2 relative to the largest dimension of the image, such that it would automatically handle landscape or portrait mode images (rather than the user specifying 3:2 vs 2:3)?

2) Are you also asking for an option to the crop to be such that it crop relative to the smaller dimension and thus fill with pad so that the result has 3:2 with background filling? This might be done with the ^ flag such as 3:2+X+Y^

Fred

User avatar
GeeMack
Posts: 607
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Re: Crop to an aspect ratio with "-crop 3:2"

Post by GeeMack » 2018-01-31T17:51:59-07:00

fmw42 wrote:
2018-01-31T13:24:04-07:00
1) Are you asking for a -define or new geometry flag that would crop 3:2 relative to the largest dimension of the image, such that it would automatically handle landscape or portrait mode images (rather than the user specifying 3:2 vs 2:3)?
The default appears to crop the largest W:H area without regard to the proportions of the input image. The first command here results in a 640x427 crop from the center of the logo. The second will produce a 320x480 image cropped from the center...

Code: Select all

magick logo: -gravity center -crop 3:2 result.png

magick logo: -gravity center -crop 2:3 result.png
My suggestion would be a flag that can be added to force the crop to follow the proportions of the input, automatically handling landscape or portrait mode. These next commands with a flag like a bang "!" for example, would produce identical 640x427 outputs...

Code: Select all

magick logo: -gravity center -crop 3:2! result.png

magick logo: -gravity center -crop 2:3! result.png
2) Are you also asking for an option to the crop to be such that it crop relative to the smaller dimension and thus fill with pad so that the result has 3:2 with background filling? This might be done with the ^ flag such as 3:2+X+Y^
Yes. I think that would be particularly useful with "-extent" because we already use that operation to increase the canvas beyond the dimension of the input image. A flag like a caret "^" for example, in a command like this would produce an output image of 640x960, with the area outside the input image filled with the current background color...

Code: Select all

magick logo: -gravity center -crop 2:3^ result.png
It could even be that "-crop 3:2" could make the largest possible 3:2 size fully inside the input image, and "-extent 3:2" could default to making the 3:2 fully include the input by adding padding as necessary. Then either one could by default follow the W:H specified in the argument, and if there is a "!" flag the crop/extent could adhere to the proportions of the input image, larger ratio dimension aligning with the longer side of the image.

These are just some thoughts based on occasional forum questions and a few situations I've encountered. I know there are fairly easy methods to get these results with simple FX expressions, but if the aspect ratio option is available for "crop" and "extent", an option or two to accommodate some of the more common needs seems like it could come in handy.

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

Re: Crop to an aspect ratio with "-crop 3:2"

Post by fmw42 » 2018-01-31T18:35:36-07:00

GeeMack wrote:The default appears to crop the largest W:H area without regard to the proportions of the input image. The first command here results in a 640x427 crop from the center of the logo. The second will produce a 320x480 image cropped from the center...

magick logo: -gravity center -crop 3:2 result.png

magick logo: -gravity center -crop 2:3 result.png
I believe that the current design crops horizontally if W:H has W>H and crop vertically if W:H has W<H.

An auto option such as -define crop:aspect=auto, seems possible, I think, by simply cropping with the larger of W:H along the largest dimension of the image. Although I have not give that much thought or prototyped it yet.

User avatar
GeeMack
Posts: 607
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Re: Crop to an aspect ratio with "-crop 3:2"

Post by GeeMack » 2018-01-31T19:43:07-07:00

fmw42 wrote:
2018-01-31T18:35:36-07:00
An auto option such as -define crop:aspect=auto, seems possible, I think, by simply cropping with the larger of W:H along the largest dimension of the image. Although I have not give that much thought or prototyped it yet.
My "real" programming skills aren't top notch, but I keep a stash of IM command snippets I've worked up over the years to do particular tasks. Variations on these crops/pads have come in handy several times.

This crops the input image to the largest 3:2 if it's landscape or square, and the largest 2:3 if it's portrait...

Code: Select all

magick input.png -gravity center \
   -extent "%[fx:w<h&&w/2>h/3?h/3*2:w]x%[h]" \
   -extent "%[fx:w>h&&w/3>h/2?h/2*3:w]x%[h]" \
   -extent "%[w]x%[fx:w<h&&w/2<h/3?w/2*3:h]" \
   -extent "%[w]x%[fx:w>=h&&w/3<h/2?w/3*2:h]" output.png
This pads to 3:2 to include the entire input image if it's landscape or square, and to 2:3 if it's portrait...

Code: Select all

magick input.png -gravity center \
   -extent "%[w]x%[fx:w>h&&w/3>h/2?w/3*2:w<h&&h/3<w/2?w/2*3:h]" \
   -extent "%[fx:w<h&&h/3>w/2?h/3*2:w>=h&&w/3<h/2?h/2*3:w]x%[h]" output.png
If I recall testing with variables, these only work if the larger value goes where the 3s are, and the equal or smaller value goes where the 2s are.

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

Re: Crop to an aspect ratio with "-crop 3:2"

Post by fmw42 » 2018-01-31T20:21:07-07:00

FYI: The following IM 6 style is how my script does it and what is currently coded in ImageMagick. I work by comparing aspect ratios.

In IM 7 style it would be:

Code: Select all

infile="monet2.jpg"
#infile="barn.jpg"
aspect="1.5"
magick "$infile" \
-gravity center \
-crop "%[fx:$aspect>=(w/h)?w:w*$aspect/(w/h)]x%[fx:$aspect>=(w/h)?h*(w/h)/$aspect:h]+0+0" \
+repage \
result.jpg
Or in IM 6 style it is:

Code: Select all

infile="monet2.jpg"
aspect="3:2"
ww=`convert -ping "$infile" -format "%w" info:`
hh=`convert -ping "$infile" -format "%h" info:`
ratio=`convert xc: -format "%[fx:$ww/$hh]" info:`
aspect1=`echo $aspect | cut -d\: -f1`
aspect2=`echo $aspect | cut -d\: -f2`
aspect=`convert xc: -format "%[fx:$aspect1/$aspect2]" info:`
test=`convert xc: -format "%[fx:$aspect>=$ratio?1:0]" info:`
if [ $test -eq 1 ]; then
    width=$ww
    height=`convert xc: -format "%[fx:$hh*$ratio/$aspect]" info:`
else
    width=`convert xc: -format "%[fx:$ww*$aspect/$ratio]" info:`
    height=$hh
fi  
convert "$infile" -gravity center -crop ${width}x${height}+0+0 +repage result.jpg

I believe this does what is needed for auto aspect processing:

Input test images:

Image
Image

Code: Select all

infile="monet2.jpg"
#infile="barn.jpg"
aspect="3:2"
inname=`convert -ping $infile -format "%t" info:`
ww=`convert -ping "$infile" -format "%w" info:`
hh=`convert -ping "$infile" -format "%h" info:`
ratio=`convert xc: -format "%[fx:max($ww,$hh)/min($ww,$hh)]" info:`
aspect1=`echo $aspect | cut -d\: -f1`
aspect2=`echo $aspect | cut -d\: -f2`
maxaspect=`convert xc: -format "%[fx:max($aspect1,$aspect2)]" info:`
minaspect=`convert xc: -format "%[fx:min($aspect1,$aspect2)]" info:`
aspect=`convert xc: -format "%[fx:$maxaspect/$minaspect]" info:`
echo "aspect1=$aspect1; aspect2=$aspect2; maxaspect=$maxaspect; minaspect=$minaspect; aspect=$aspect;"
if [ $ww -gt $hh ]; then
    width=$ww
    height=`convert xc: -format "%[fx:$hh*$ratio/$aspect]" info:`
else
    width=`convert xc: -format "%[fx:$ww*$ratio/$aspect]" info:`
    height=$hh
fi  
convert "$infile" -gravity center -crop ${width}x${height}+0+0 +repage ${inname}_auto_${aspect}.jpg
Image
Image

User avatar
anthony
Posts: 8886
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Crop to an aspect ratio with "-crop 3:2"

Post by anthony » 2018-02-07T17:08:52-07:00

This is a viewport crop, which is similar to the calculated 'Centered Square Crop'
http://www.imagemagick.org/Usage/distor ... red_square
of course with IMv7 you can do this using -extent instead ;-)

It is also related to a rotate-and-resize-crop method
http://www.imagemagick.org/Usage/distor ... te_methods

However a 'crop to aspect ratio' operator would make a nice addition to IM.

Added a section to IM examples pointing to this discussion.
http://www.imagemagick.org/Usage/crop/#advanced
To Appear in a few hours
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
http://www.imagemagick.org/Usage/

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

Re: Crop to an aspect ratio with "-crop 3:2"

Post by fmw42 » 2018-02-07T17:12:17-07:00

It seemed to be often requested and useful to integrate it into IM so that we do not have to explain the FX calculations too often to achieve that by either IM 6 or IM 7

User avatar
anthony
Posts: 8886
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Crop to an aspect ratio with "-crop 3:2"

Post by anthony » 2018-02-07T17:52:33-07:00

Whether to actually switch from 3:2 to 2:3 depending on image orientation may need to a option for users that do NOT want to do it (EG; they are fitting photos into a thumbnail array).

I do think this will need to be a separate option, as there is currently no way to determine if a ':' was used in a 'geometry like' option.

Code: Select all

convert logo: -gravity center -extent 2:3 show:
convert: invalid geometry `2:3' @ error/geometry.c/ParseGravityGeometry/1185.
At least not unless a new flag was added to allow using : as separators and flagging if one was used for operators that use it!
And crop is already complex enough. This is sort of what happened when I added '(near) equal area cropping'
Sometimes I think it would be better if crop was split up (with backwards compatibility) into a option of different options, as internally they are different library functions.

EG: Tile cropping, Equal cropping, viewport cropping (which is similar to and predated 'extent' in fact -extent is more a viewport crop than viewport cropping is!)
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
http://www.imagemagick.org/Usage/

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

Re: Crop to an aspect ratio with "-crop 3:2"

Post by fmw42 » 2018-02-07T19:30:59-07:00

A -define could be used to specify to use the automatic crop to 3:2 or 2:3 according to which dimension os larger.

Post Reply