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

Closed
wichert opened this Issue Aug 2, 2012 · 10 comments

Comments

Projects
None yet
4 participants
Contributor

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.

Contributor

dhardy92 commented Aug 2, 2012

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

Contributor

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?

Owner

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.

Contributor

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.

Owner

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.

Contributor

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.

Contributor

wichert commented Aug 16, 2012

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

Owner

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
wrote:

@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

Owner

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.

Owner

heynemann commented Aug 20, 2012

Tomorrow?

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