Skip to content

Commit

Permalink
Keep ICC profile when saving image, if present
Browse files Browse the repository at this point in the history
  • Loading branch information
siovene committed Jul 6, 2021
1 parent 208057c commit 0b71807
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 3 deletions.
9 changes: 8 additions & 1 deletion README.rst
Expand Up @@ -134,7 +134,14 @@ during scaling.
Changes the quality of the output JPEG thumbnail. Defaults to ``85``.

In Python code, this is given as a separate option to the ``get_thumbnail``
method rather than just alter the other
method rather than just alter the other.

``keep_icc_profile``
--------------------

If `True`, when saving a thumbnail with the alias that defines this option, the
ICC profile of the image will be preserved in the thumbnail, if present in the first place.


Other options
-------------
Expand Down
3 changes: 3 additions & 0 deletions easy_thumbnails/engine.py
@@ -1,4 +1,5 @@
import os

from io import BytesIO

from PIL import Image
Expand Down Expand Up @@ -57,6 +58,8 @@ def save_image(image, destination=None, filename=None, **options):
max(image.size) >= settings.THUMBNAIL_PROGRESSIVE):
options['progressive'] = True
try:
if options.pop('keep_icc_profile', False):
options['icc_profile'] = image.info.get('icc_profile')
image.save(destination, format=format, optimize=1, **options)
saved = True
except IOError:
Expand Down
4 changes: 3 additions & 1 deletion easy_thumbnails/files.py
Expand Up @@ -150,6 +150,7 @@ class ThumbnailFile(ImageFieldFile):
This can be used just like a Django model instance's property for a file
field (i.e. an ``ImageFieldFile`` object).
"""

def __init__(self, name, file=None, storage=None, thumbnail_options=None,
*args, **kwargs):
fake_field = FakeField(storage=storage)
Expand Down Expand Up @@ -400,7 +401,7 @@ def generate_thumbnail(self, thumbnail_options, high_resolution=False,

img = engine.save_image(
thumbnail_image, filename=filename, quality=quality,
subsampling=subsampling)
subsampling=subsampling, keep_icc_profile=thumbnail_options.get('keep_icc_profile', False))
data = img.read()

thumbnail = ThumbnailFile(
Expand Down Expand Up @@ -653,6 +654,7 @@ class ThumbnailerFieldFile(FieldFile, Thumbnailer):
A field file which provides some methods for generating (and returning)
thumbnail images.
"""

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_storage = self.field.storage
Expand Down
13 changes: 12 additions & 1 deletion easy_thumbnails/tests/test_engine.py
@@ -1,5 +1,5 @@
from unittest import TestCase
from PIL import Image
from PIL import Image, ImageCms

from easy_thumbnails import engine

Expand All @@ -17,3 +17,14 @@ def test_save_jpeg_la(self):
data = engine.save_image(source, filename='test.jpg')
with Image.open(data) as img:
self.assertEqual(img.mode, 'L')

def test_save_with_icc_profile(self):
source = Image.new('RGB', (100, 100), (255, 255, 255))
profile = ImageCms.createProfile('sRGB')
source.save('source.jpg', icc_profile=ImageCms.ImageCmsProfile(profile).tobytes())
source = Image.open('source.jpg')

data = engine.save_image(source, filename='test.jpg', keep_icc_profile=True)
img = Image.open(data)

self.assertNotEqual(img.info.get('icc_profile'), None)

0 comments on commit 0b71807

Please sign in to comment.