Is there a simple solution to trim whitespace on the image in PIL?
ImageMagick has easy support for it in the following way:
convert test.jpeg -fuzz 7% -trim test_trimmed.jpeg
I found a solution for PIL:
from PIL import Image, ImageChops
def trim(im, border):
bg = Image.new(im.mode, im.size, border)
diff = ImageChops.difference(im, bg)
bbox = diff.getbbox()
if bbox:
return im.crop(bbox)
But this solution has disadvantages:
- I need to define
bordercolor, it is not a big deal for me, my images has a white background - And the most disadvantage, This PIL solution doesn’t support ImageMagick’s
-fuzzkey. To add some fuzzy cropping. as I can have some jpeg compression artifacts and unneeded huge shadows.
Maybe PIL has some built-in functions for it?
Or there is some fast solution?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
I don’t think there is anything built in to PIL that can do this. But I’ve modified your code so it will do it.
- It gets the border colour from the top left pixel, using
getpixel, so you don’t need to pass the colour. - Subtracts a scalar from the differenced image, this is a quick way of saturating all values under
100, 100, 100(in my example) to zero. So is a neat way to remove any ‘wobble’ resulting from compression.
Code:
from PIL import Image, ImageChops
def trim(im):
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()
if bbox:
return im.crop(bbox)
im = Image.open("bord3.jpg")
im = trim(im)
im.show()
Heavily compressed jpeg:
Cropped: 
Noisy jpeg:
Cropped: 
Method 2
Use wand http://docs.wand-py.org/en/0.3-maintenance/wand/image.html
trim(color=None, fuzz=0)
Remove solid border from image. Uses top left pixel as a guide by default, or you can also specify the color to remove.
Method 3
using trim function at ufp.image module.
import ufp.image
import PIL
im = PIL.Image.open('test.jpg', 'r')
trimed = ufp.image.trim(im, fuzz=13.3)
trimed.save('trimed.jpg')
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0