easy-thumbnails icon indicating copy to clipboard operation
easy-thumbnails copied to clipboard

Images lose their icc_profile

Open rchrd2 opened this issue 10 years ago • 13 comments
trafficstars

Loses icc_profile and looks less vibrant

image = ThumbnailerImageField(upload_to='upload/%Y/%m/%d', blank=True, default=None, resize_source=dict(size=(800, 800), sharpen=False,))

Does not lose icc_profile

image = ThumbnailerImageField(upload_to='upload/%Y/%m/%d', blank=True, default=None)

See http://stackoverflow.com/questions/13672777/python-pil-changing-colour-profile-to-untagged-rgb-on-crop-scale-and-save

using version 2.2

rchrd2 avatar Apr 10 '15 22:04 rchrd2

Presumably the icc profile is dropped to reduce file size. Even if it wasn't dropped, mobile browsers tend to ignore colour profiles in the interests of performance, meaning the colours are still muted.

A good solution is to convert the colour profile of the image to sRGB (which is aimed at consumer screens) before the profile is dropped. We have some code that will do this at https://github.com/ixc/icekit-imagetools/blob/develop/imagetools/utils/srgb.py

Question for @SmileyChris : should converting to sRGB before dropping the profile be the default easy-thumbnails behaviour?

cogat avatar Apr 04 '17 00:04 cogat

probably related: #397

fdemmer avatar Aug 04 '18 10:08 fdemmer

I have made an image processor that converts an image to sRGB colour profile and RGB colour space so that there is the minimum of visual disruption when the colour profile is dropped. Add it to the beginning of THUMBNAIL_PROCESSORS as per https://easy-thumbnails.readthedocs.io/en/latest/ref/processors/#custom-processors.

https://gist.github.com/cogat/fbdfeb099564ef0cdda8491b0d65557c

I think this can replace the default colorspace processor.

cogat avatar Feb 03 '20 05:02 cogat

@cogat thanks for that solution. It works for me! However, I would like to keep the ICC profile embedded instead of applying it. Any suggestions on how to go regarding that? Thanks!

siovene avatar Sep 27 '20 16:09 siovene

If you want to keep the profile embedded, be aware that mobile browsers (at least last time I checked, a few years ago) discard the profile and so will render uncorrected (dull) colours.

I'm guessing there is a processor in easythumbnails - or an action of PIL, that discards the ICC profile (see the two contrasting cases up top). I think that processor needs to be skipped or reimplemented in order to prevent the profile discarding.

cogat avatar Sep 27 '20 17:09 cogat

First place to check/bypass would be https://github.com/SmileyChris/easy-thumbnails/blob/master/easy_thumbnails/processors.py#L38 which ensures an RGB colour space. NB colour space (RGB/CMYK) is a different concept to ICC profile.

cogat avatar Sep 27 '20 17:09 cogat

Hi @cogat, I investigated, and it's not a processor in easythumbnails that discards the ICC profile.

It's saving the image in engine.py::save_image.

At this line: image.save(destination, format=format, optimize=1, **options).

I debugged, and at that point, image had an ICC profile and an exif:

Screen Shot 2020-10-01 at 10 09 04

As soon as we exit from save_image, and return to generate_thumbnail, I read the data back into an Image, and the ICC profile is gone:

Screen Shot 2020-10-01 at 10 12 00

Got any suggestions? Thanks!

siovene avatar Oct 01 '20 08:10 siovene

Hey @siovene unfortunately I don't have a thumbnails project warmed up to look at or test with, but https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#jpeg seems to say if you could pass the icc_profile in as one of the options to save_image then it would get saved into the jpg.

save_image is called here and so if you were to use your own subclass of Thumbnailer and override the call, then that might work.

However, at this point you might be re-implementing or overriding so much that it is easier to create your own thumbnail script?

cogat avatar Oct 01 '20 10:10 cogat

I think I'll go with a fork and sending a pull request. I'm involved too deeply in easy-thumbnailer to replace it. Thanks!

siovene avatar Oct 01 '20 11:10 siovene

It's been a while since I used this project, but I seem to remember that pillow doesn't maintain any metadata once you start transforming images.

You need to extract extract metadata like ICC, do any image transforms, then when saving it with pillow, pass the ICC metadata into the save method.

Keep in mind that this project is a thumbnailer, the point is to have Small (file size) image output. ICC, exif metadata can actually be quite large - sometimes larger than the thumbnail itself!

Note that depending on the ICC profile, you may be able to replace it with a much smaller substitute without visible degradation.

jaddison avatar Oct 01 '20 15:10 jaddison

Hi @jaddison, true, regarding file size. However, in my case, I need thumbnails to be as color correct as possible. I'm implementing this so that there would be settings to specify which thumbnail aliases should keep the ICC profile, and which should discard them.

For my small thumbnails, I would discard the ICC and apply it in the sRGB space. For the large thumbnails I would keep it.

I use the word thumbnail very loosely because in my project some of them are quite large.

siovene avatar Oct 01 '20 19:10 siovene

Can anyone have a look at my PR? I understand if it takes longer to get merged, but if I could get a summary opinion I could use it in my fork while I wait for the merge. I'm forked from 2.6 anyway because I'm on Django 1.11.

siovene avatar Oct 02 '20 12:10 siovene

I have an image that uses the ProPhoto RGB color profile. When I generated a thumbnail for the image, the thumbnail's colors looked pretty awful. I searched online, found this issue, tried out PR #554 by @siovene, and my problem was solved. Is there anything preventing it from being merged?

ataylor32 avatar Dec 07 '22 03:12 ataylor32