With imagemagick, I'd like to crop an image, in a minimal fashion, so that it fits a given aspect ratio.
Example: given an image of, say, 3038 x 2014 px, I want to crop it to have a 3:2 aspect ratio. The resulting image would then be 3021 x 2014 px, cropped from the, say, center of the original image.
So looking for a command looking something like convert in.jpg -gravity center -crop_to_aspect_ratio 3:2 out.jpg
.
Crop Image to an Aspect RatioClick Upload an image and select the image you want to crop. Under step 2, click the Fixed Aspect Ratio button, then enter that ratio, such as 5 and 2, and click Change. Drag a rectangle over the image to select the area you want. Move the selection as needed, then click Crop.
To resize an image to specific dimensions, use the convert command with an input file, the -resize parameter, your preferred dimensions, and an output filename: convert original. png -resize 100x100 new.
-crop 3:2
works since January 6th, 2018.
magick convert in.jpg -gravity center -crop 3:2 out.jpg
Warning/reminder: if you don't use -gravity center
, you will get two output files:
As fmw42 points out, PNG files store the virtual canvas size. +repage
is recommended.
magick convert in.png -gravity center -crop 3:2 +repage out+repage.png
GIMP, IrfanView, Chrome and Windows Explorer don't show any difference, but Imagemagick knows:
magick identify out*png out_stndrd.png PNG 252x168 314x168+31+0 8-bit sRGB 78557B 0.000u 0:00.000 out+repage.png PNG 252x168 252x168+0+0 8-bit sRGB 78529B 0.000u 0:00.000
convert in.jpg -gravity center -crop 3:2 out.jpg
convert in. -gravity center -crop 3:2 +repage out.png
Note: you need to add magick
before any convert
for v7.
If your goal at the end is to have a certain resolution (for example 1920x1080) then it's easy, using -geometry
, the circumflex/hat/roof/house symbol (^
) and -crop
:
convert in.jpg -geometry 1920x1080^ -gravity center -crop 1920x1080+0+0 out.jpg
To loop over multiple jpg files:
for i in *jpg do convert "$i" -geometry 1920x1080^ -gravity center -crop 1920x1080+0+0 out-"$i" done
If you want to avoid scaling, you have to calculate the new length of the cropped side outside of Imagemagick. This is more involved:
aw=16 #desired aspect ratio width... ah=9 #and height in="in.jpg" out="out.jpg" wid=`convert "$in" -format "%[w]" info:` hei=`convert "$in" -format "%[h]" info:` tarar=`echo $aw/$ah | bc -l` imgar=`convert "$in" -format "%[fx:w/h]" info:` if (( $(bc <<< "$tarar > $imgar") )) then nhei=`echo $wid/$tarar | bc` convert "$in" -gravity center -crop ${wid}x${nhei}+0+0 "$out" elif (( $(bc <<< "$tarar < $imgar") )) then nwid=`echo $hei*$tarar | bc` convert "$in" -gravity center -crop ${nwid}x${hei}+0+0 "$out" else cp "$in" "$out" fi
I'm using 16:9 in the examples, expecting it to be more useful than 3:2 to most readers. Change both occurrences of 1920x1080
in solution 1 or the aw
/ah
variables in solution 2 to get your desired aspect ratio.
Photo credit: Anders Krusberg / Peabody Awards
Recent versions of Imagemagick (since 6.9.9-34) have an aspect crop. So you can do:
Input:
convert barn.jpg -gravity center -crop 3:2 +repage barn_crop_3to2.png
The output is 400x267+0+0. But note that the +repage is needed to remove the virtual canvas of 400x299+0+16, because PNG output supports virtual canvas. JPG output would not need the +repage, since it does not support a virtual canvas.
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