1
votes

I'm trying to use ImageMagick to emulate the rotate and crop function of Gimp to use it on a batch of images.

What I would do in Gimp is to open the .jpg image, use the rotation tool with the following options: 0.2°, cubic interpolation and crop with the original image ratio. After that with just another crop around the image borders the process is complete and I can save the image as .png

I'm not using Gimp because the built in procedure gimp-drawable-transform-rotate-default only accepts radians with two decimals. I tried to find a way to edit that procudere and to create my own but I wasn't able to do so

I wal also suggested to use ImageMagick because the batch is very large (50k+ images), therefore, can you help me with the console command to emulate what I would do with Gimp? In particular the important part is the crop with the original image ratio

Edit:

When you rotate an image, if the ° aren't 90-180-270 etc.., the size of the image is increased and therefore new pixels must be created. The following crop must:

  1. Delete all the pixels added during the rotation to fill the blank spaces
  2. The final ratio has to be as close ad possible to the initial one
  3. What comes to be cropped (ofc the crop has to be centered) that was present in the original image has to be the as little as possible

Basically you should't be able to see the differences between the original and the edited images just by looking at them

The procedure that I described for Gimp already did everything but it works only on one image at a time

2
If the rotation is the same for all images, you can do that with mogrify in ImageMagick on a whole folder of files. It loops through each image in the folder. Alternately you can write a script to loop over each image and do that. Cubic Convolution would be -filter Catrom. If you know Python, then you could do the script looping and processing in Python Wand. See imagemagick.org/Usage/basics/#mogrify and docs.wand-py.org/en/0.5.7fmw42
Yes I do know python but for what I can see the rotation and crop are vary basic in wand, for example during rotation I can't specify the interpolation to use. Plus I think Gimp crop is optimized to find out the smallest crop that both keeps the original ratio of the image and cuts the borders added by the rotation. I decided not to use PIL because there wasn't a way to do so for 50k+ images without risking to crop too much in any of them. I'll probably look more into IM and see if I can find out how to change their basic scriptsLello_Lelli
See docs.wand-py.org/en/0.5.7/wand/image.html. Use filter type Catrom. Use distort with distortion method scale_rotate_translate and fix the scale and translation to 0 to just do rotation. See crop for cropping and compute the width and height to preserve aspect ratio of the input.fmw42
Please clarify your cropping requirements. You may be interested in the inner trim option for ImageMagick -trim at imagemagick.org/discourse-server/viewtopic.php?f=4&t=35579fmw42
Edit with better detail about the cropLello_Lelli

2 Answers

1
votes

Here is perhaps a better approach (using ImageMagick 6). Rather than relying upon the fuzz value to trim the rotated image black border, one should be able to compute the amount that needs to be shaved from each side given the angle of rotation and the dimensions of the image. (Unix Syntax)

Input (original)

enter image description here

angle=0.2
convert barn.jpg -background black -rotate $angle barn_rotated.png


Rotated Image:

enter image description here

WxH=`convert barn.jpg -format "%wx%h" info:`
ww=`echo "$WxH" | cut -dx -f1`
hh=`echo "$WxH" | cut -dx -f2`
aspect="${ww}:${hh}"
xshave=`convert xc: -format "%[fx:ceil($hh*sin($angle*pi/180))+1]" info:`
yshave=`convert xc: -format "%[fx:ceil($ww*sin($angle*pi/180))+1]" info:`
convert barn_rotated.png -shave ${xshave}x${yshave} \
-gravity center -crop "$aspect" +repage barn_rotated_shaved_cropped.png


Shaved And Cropped to Aspect Image:

enter image description here

If using ImageMagick 7, replace convert with magick.

0
votes

Here is an example using ImageMagick 6.

First, I get and print the input aspect ratio. Then I rotated it by 0.2 deg. Then I trim it to remove the black border. Then I crop it to the input aspect ratio and print the output aspect ratio. Unix Syntax below.

Input:

enter image description here

aspect=`convert barn.jpg -format "%w:%h" info:`
convert barn.jpg -format "input_aspect=%[fx:w/h]\n" -write info: -background black -rotate 0.2 barn_rotated.png

input_aspect=1.33779


enter image description here

convert barn_rotated.png -fuzz 16% -define trim:percent-background=0% -trim +repage \
-gravity center -crop "$aspect" +repage -format "output_aspect=%[fx:w/h]\n" -write info: barn_cropped.jpg

output_aspect=1.33969


enter image description here

If using ImageMagick 7, you can do it all in one command line:

magick barn.jpg -set option:aspect "%w:%h" -format "input_aspect=%[fx:w/h]\n" -write info: \
-background black -rotate 0.2 +write barn_rotated.png \
-fuzz 16% -define trim:percent-background=0% -trim +repage \
-gravity center -crop "%[aspect]" \
+repage -format "output_aspect=%[fx:w/h]\n" -write info: \
barn_cropped.jpg


The fuzz value is going to be image dependent.