Fixes TIFFImagePlugin ICC color profile saving.

In the TIFF code saving icc_profile is conditional on tag_v2 being set which doesn't make sense to me. I believe this is merely an indentation typo.

I've been trying to save TIFFs with im.info['icc_profile'] set and compression=raw, but unfortunately this results in TIFFs without ICC color profiles.
With the attached patch TIFFs with said conditions will be saved with the profile set in im.info['icc_profile'].

Note: There are a number of different conditions that need to be met for code to succeed in saving with the profile since it branches between using libtiff and ImageFile._save(..), and the libtiff code does not currently save the ICC color profile.
For instance setting compression=tiff_lzw will result in using libtiff and no profile will be saved.
This commit is contained in:
Clement Skau 2016-08-22 19:47:49 +09:00 committed by Clement Skau
parent 5aeb0ed972
commit caf53b05ec
2 changed files with 20 additions and 4 deletions

View File

@ -1366,10 +1366,10 @@ def _save(im, fp, filename):
ifd[key] = im.tag_v2[key] ifd[key] = im.tag_v2[key]
ifd.tagtype[key] = im.tag_v2.tagtype[key] ifd.tagtype[key] = im.tag_v2.tagtype[key]
# preserve ICC profile (should also work when saving other formats # preserve ICC profile (should also work when saving other formats
# which support profiles as TIFF) -- 2008-06-06 Florian Hoech # which support profiles as TIFF) -- 2008-06-06 Florian Hoech
if "icc_profile" in im.info: if "icc_profile" in im.info:
ifd[ICCPROFILE] = im.info["icc_profile"] ifd[ICCPROFILE] = im.info["icc_profile"]
for key, name in [(IMAGEDESCRIPTION, "description"), for key, name in [(IMAGEDESCRIPTION, "description"),
(X_RESOLUTION, "resolution"), (X_RESOLUTION, "resolution"),

View File

@ -499,5 +499,21 @@ class TestFileTiff(PillowTestCase):
with Image.open(mp) as im: with Image.open(mp) as im:
self.assertEqual(im.n_frames, 3) self.assertEqual(im.n_frames, 3)
def test_saving_icc_profile(self):
# Tests saving TIFF with icc_profile set.
# At the time of writing this will only work for non-compressed tiffs
# as libtiff does not support embedded ICC profiles, ImageFile._save(..)
# however does.
im = Image.new('RGB', (1, 1))
im.info['icc_profile'] = 'Dummy value'
# Try save-load round trip to make sure both handle icc_profile.
tmpfile = self.tempfile('temp.tif')
im.save(tmpfile, 'TIFF', compression='raw')
reloaded = Image.open(tmpfile)
self.assertEqual(b'Dummy value', reloaded.info['icc_profile'])
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()