PIL convert('L') to greyscale distorts some images
I'm converting some images to greyscale with the easy-thumbnails Django app. Most of them are fine, but a handful are getting partially or totally messed up. The same error is occurring on two different m开发者_StackOverflow社区achines, so I don't think it's an issue of a PIL install being corrupt or something.
Here are a couple examples:
Original image http://66.228.39.122/uploads/companies/alerts_logo.png Disorted version http://66.228.39.122/uploads/companies/alerts_logo.png.198x150_q85_bw_upscale.jpg
Original image http://66.228.39.122/uploads/companies/HashableLogo_Color_RGB.png Disorted version http://66.228.39.122/uploads/companies/HashableLogo_Color_RGB.png.198x150_q85_bw_upscale.jpg
Any suggestions? Are the original images themselves corrupt in some subtle way? Should I recompile PIL with --no-random-distort or something? I've looked at the relevant part of the easy-thumbnails source and it's just calling image.convert('L'), so I think the problem must lie either inside PIL or with the images themselves. the way the exclamation mark is distorted in the Alerts.com logo makes me think that perhaps there's some kind of encoding issue, since the outline of the exclamation mark is angled and its color appears to be contributing to a larger grey splotch...but the Hashable logo doesn't show quite the same problem. Maybe they are two different problems. Thanks for any suggestions/thoughts/advice.
Update: Actually, if I remove the bw
filter and add instead replace_alpha="red"
I get similar (though not greyscaled) distortions, so it looks like it is probably PIL unhappy with how the images are encoded or something. Unfortunately I need non-technical people to be able to upload new images and have them work, so a programmatic solution is necessary, rather than just resaving the images manually.
Update 2: I actually experimented a bit and found that resaving the PNGs with GIMP solves the problem, if I resave once and check the box for saving color information for transparent pixels, and then resave a second time with that box unchecked. Just doing the first or the second of these doesn't solve the problem, and doing both and then the first again re-causes it. And it still doesn't handle partial transparency well. Since this is tedious and imperfect, a programmatic solution would still be great if there are any PIL or PNG encoding whizzes out there.
Here is some code that will convert an image to grayscale, without losing quality.
from PIL import Image, ImageOps
image = Image.open('filepath')
image = ImageOps.grayscale(image)
image.save('filepath', quality=95)
精彩评论