Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Option to strip surrounding whitespace #116

wichert opened this Issue Aug 2, 2012 · 10 comments


None yet
4 participants

wichert commented Aug 2, 2012

When scaling images we would like to crop out surrounding whitespace. I'm looking at how this can be implemented, but I'm not quite sure where to start yet.


dhardy92 commented Aug 2, 2012

It sounds like some feature detection.
Maybe you should start with it ?


wichert commented Aug 2, 2012

This PIL code does the trick:

bg = Image.new(im.mode, im.size, im.getpixel((0,0)))
diff = ImageChops.difference(im, bg)
diff = ImageChops.add(diff, diff, 2.0, -100)
bbox = diff.getbbox()
cropped = im.crop(bbox)

For something opencv based perhaps cvFindContours is the thing to use?


cezarsa commented Aug 2, 2012

Curious that me and @heynemann were discussing a use case that would require whitespace trimming just this week.
I'll take a look at writing a cross-engine implementation of this operation tomorrow.


wichert commented Aug 3, 2012

The PIL code I put above was not entirely correct: the ImageChops.add is loosing too much details which make it likely that you will be cropping far too much (consider photo of a white article on a white background).

This routine fixes that:

def crop_surrounding_whitespace(image):
    """Remove surrounding empty space around an image.

    This implemenation assumes that the surrounding space has the same colour
    as the top leftmost pixel.

    :param image: PIL image
    :rtype: PIL image
    bg = PIL.Image.new(image.mode, image.size, image.getpixel((0, 0)))
    diff = PIL.ImageChops.difference(image, bg)
    bbox = diff.getbbox()
    if not bbox:
        return image
    return image.crop(bbox)

there is another problem though: if you the final image needs to fit in and fill a box you may need to crop again, but if you do that after cropping the border you may then suddenly need to crop real image parts. To fix that the whitespace cropping logic should try to match the desired target aspect ratio when it crops.


heynemann commented Aug 3, 2012

I see. I'm thinking of how we would implement it in GraphicsMagick. Me and Cezar were discussing a way of implementing this in C as an extension that can be called both from pil or graphicsmagick.

That extension would return the new byte array, the new width and new height.

Cezar will work on this in the afternoon today.


wichert commented Aug 3, 2012

ImageMagick has a C implementation of this that might be interesting;
look for the implementation of trim -fuzzy there. What they seem to be
doing (based on a very quick code introspection) is classifying images
into groups based on channel histograms, and then use that information
to walk around the borders of the image and look for patches that are in
the same group and crop based on that information.


wichert commented Aug 16, 2012

@heynemann have you been able to make any progress on this?


cezarsa commented Aug 16, 2012

I got this working locally, I'll push latter today.

Cezar Sá Espinola

Sent from my android device.
On Aug 16, 2012 5:36 AM, "Wichert Akkerman" notifications@github.com

@heynemann https://github.com/heynemann have you been able to make any
progress on this?

Reply to this email directly or view it on GitHubhttps://github.com/globocom/thumbor/issues/116#issuecomment-7779625.

@cezarsa cezarsa closed this in 42e2374 Aug 17, 2012


cezarsa commented Aug 17, 2012

@wichert I'll add some docs tomorrow, but take a look at the commit message for some basic usage instructions. This implementation should work in a similar way to ImageMagick with -trim and -fuzz, considering colors inside within a specified distance as similar.


heynemann commented Aug 20, 2012


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment