Jakob
Jakob

Reputation: 3662

crop image with imagemagick offset given in percentage

imagemagick's crop command supports cropping to a percentage of an image but the offset values must be specified in pixel values, e.g.:

convert image.png -crop 50%x+10+20

I want to crop with offset values x and y given in percentage of the image width, and height respectively. The pixel values can be calculated, for instance if the image size is 100x200 an offset of 10% would result in 10 and 20 respectively. Is it possible to do this calculation as part of the call to convert? Width and height are available as %w and %h at some places, but this does not work:

convert image.png -crop 50%x+(0.1*%w)+(0.1*%h)

Upvotes: 3

Views: 3378

Answers (3)

GeeMack
GeeMack

Reputation: 5385

If you're running IM v6 you can use FX expressions with "-set" to set image attributes. By setting the page geometry you can specify the offsets to a calculated percentage and do the crop like this...

convert image.png -set page -%[fx:w*0.1]-%[fx:h*0.1] -crop 50%x+0+0 result.png

That reads the image, sets the geometry for the upper left corner to a location outside the original canvas, and crops to the new top left corner specified by the geometry.

Note the offsets are negative numbers.

Also, if you're doing additional processing in the same command you'll probably want to "+repage" after the crop in order to reset the page geometry to the new WxH+0+0.

Edited to add: You can even include the width and height dimensions for the crop when using "-set page". This command would crop an output of 50% the input width and height, and starting at 10% in from the left and top...

convert image.png \
   -set page %[fx:w*0.5]x%[fx:h*0.5]-%[fx:w*0.1]-%[fx:h*0.1] -crop +0+0 result.png

Notice how the crop operation is simply "-crop +0+0" since the dimensions and offsets are in the page geometry.

This method lets you use more complex calculations than just using a percent or number of pixels for the cropped output dimensions.

Upvotes: 4

fmw42
fmw42

Reputation: 53089

You cannot do that in ImageMagick 6. But you can do that in ImageMagick 7.

magick image.png -crop "50%x+%[fx:0.1*w]+%[fx:0.1*h]" +repage result.png


In ImageMagick 6, you need to do the computations ahead of the command, store them in a variable and use the variable in the crop command.

However, in ImageMagick 6, you can do the equivalent using -distort with viewport processing as follows:

convert image.png -set option:distort:viewport "%[fx:0.5*w]x%[fx:0.5*h]+%[fx:0.1*w]+%[fx:0.1*h]" -filter point -distort SRT 0 result.png


Upvotes: 2

Mark Setchell
Mark Setchell

Reputation: 207365

With v7 ImageMagick, make start image:

magick -size 200x100 gradient: a.jpg

Now crop using lots of calculated widths, heights, offsets:

magick a.jpg -crop "%[fx:w*0.9]x%[fx:h*0.8]+%[fx:w*0.1]+%[fx:h*0.05]" b.png

Check:

identify b.png
b.png PNG 180x80 200x100+20+5 8-bit Gray 256c 408B 0.000u 0:00.000

If you only have v6, use bash and integer arithmetic:

read w h < <(identify -format "%w %h" a.jpg)
convert a.jpg -crop $((w*80/100))x$((h*90/100))+$((w*10/100))+$((h*5/100))  result.png

Check:

identify result.png
result.png PNG 160x90 200x100+20+5 8-bit Gray 256c 412B 0.000u 0:00.000

Upvotes: 3

Related Questions