Viktor Nilsson
Viktor Nilsson

Reputation: 1703

How to trim/crop an image uniformly in ImageMagick?

Assume I have an original image (gray backgorund) with a black circle a bit down to the right (not centered), and the minimum space from any edge of the circle to the edge is, lets say, 75px. I would like to trim the same amount of space on all sides, and the space should be the maximum space possible without cropping the actual object in the image (area in magenta in image). Would love to hear how this could be solved.

Not centered object

Thanks in advance!

Upvotes: 0

Views: 750

Answers (2)

rostok
rostok

Reputation: 2137

I assume that you want to trim your image (or shave in ImageMagick terms) by minimal horizontal or vertical distance to edge. If so this can be done with this one liner:

convert circle.png -trim -set page "%[fx:page.width-min(page.width-page.x-w,page.height-page.y-h)*2]x%[fx:page.height-min(page.width-page.x-w,page.height-page.y-h)*2]+%[fx:page.x-min(page.width-page.x-w,page.height-page.y-h)]+%[fx:page.y-min(page.width-page.x-w,page.height-page.y-h)]" -background none -flatten output.png  

This may look complicated but in reality isn't. First trim the image. The result will still have stored information on page geometry including original width, height and actual offsets. With this info I can set the page geometry (correct width & height and new offsets) using ImageMagick FX expressions. Finally, flattening the image will produce desired output.

Upvotes: 1

emcconville
emcconville

Reputation: 24419

If I understand the question correctly, you want to trim an image not based on minimum bounding rectangle, but outer bounding rectangle.

I would do something like this..

Given I create an image with.

convert -size 200x200 xc:gray75 -fill black -draw 'circle 125 125 150 125' base.png

base image

I would drop the image to a binary edge & trim everything down to the minimum bounding rectangle.

convert base.png -canny 1x1 -trim mbr.png

find mbr

This will generate mbr.png image which will also have the original page information. The page information can be extracted with identify utility to calculate the outer bounding rectangle.

sX=$(identify -format '%W-(0 %X)-%w\n' mbr.png | bc)
sY=$(identify -format '%H-(0 %Y)-%h\n' mbr.png | bc)

Finally apply the calculated result(s) with -shave back on the original image.

convert base.png -shave "${sX}x${sY}" out.png

uniform crop

Upvotes: 3

Related Questions