-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resizing may result in degraded quality because gamma is not compensated #1604
Comments
There is an SO question providing a workaround using numpy. |
There is essentially no color space awareness in Pillow by default. It's possible to have some compiled in, but it's optional. So it's not terribly surprising that it's not taking one specific colorspace into account when doing geometric transformations. If you really wish to do it properly, you're probably better off doing the operations in L_a_b space instead of sRGB anyway. |
Right. For future reference, this is one way to implement transformations in linearized RGB color space: from PIL import Image, ImageCms
from cStringIO import StringIO
from urllib2 import urlopen
f = urlopen('http://www.4p8.com/eric.brasseur/gamma_dalai_lama_gray.jpg')
#f = urlopen('http://www.4p8.com/eric.brasseur/gamma_cloud_gate.jpg')
img = Image.open(StringIO(f.read()))
img.show()
newsize = tuple([i/2 for i in img.size])
# Load profiles.
srgb_profile = ImageCms.getOpenProfile("/usr/share/color/icc/sRGB.icc")
lsrgb_profile = ImageCms.getOpenProfile("linearized-sRGB.icc")
# Linearize RGB color space, resize and convert back to sRGB.
if not img.mode in ('RGB', 'RGBA'):
img = img.convert('RGB')
lsrgbimg = ImageCms.profileToProfile(img, srgb_profile, lsrgb_profile)
lsrgbscaled = lsrgbimg.resize(newsize, Image.ANTIALIAS)
srgbscaled = ImageCms.profileToProfile(lsrgbscaled, lsrgb_profile, srgb_profile)
srgbscaled.show() Note, that @wiredfool thanks for the quick response and the pointers. |
Colorspace aware transforms might be something that's appropriate for inclusion with the ImageCMS portion. (I assume that we'd be able to either include or generate a linear sRGB profile, and that there wouldn't be copyright issues like we've had with some of the other profiles) The one tricky bit is that you'd really want to do one conversion into linear space, and then do all of the transforms, and then transform out. Otherwise there would likely be some pretty horrible precision losses for repeated operations, especially given that we're limited to 8 bits per channel for color images. |
What is the reason for this limitation? |
There's no support anywhere in the C layer for more than 32 bits per pixel, nor more than 8 bits per channel. It could be added, but it would be a large job and so far, no one has needed it enough to do it. |
This is extremely unfortunate. Lack of native sRGB support or 16-bit integer / 32-bit float per channel is a deal breaker. It breaks almost all transforms. Resizing, rotations, provided and custom ops, line drawing with alpha, filters, blurs, The provided 'workaround' is not actually working as it should, because it forces you to work in linear color space (which will result in very poor color quality in darker regions), but that is not really a good idea when using 8-bit per channel. |
Citing from http://www.4p8.com/eric.brasseur/gamma.html
Pillow seems to be affected by that problem too as the following test script demonstrates:
The text was updated successfully, but these errors were encountered: