From ca89d431baf4bdd50473091c9482a9206f1b5191 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 13 May 2015 16:39:25 +1000 Subject: [PATCH 1/2] To avoid modifications, copy image when saving in GifImagePlugin --- PIL/GifImagePlugin.py | 2 +- Tests/test_file_gif.py | 10 +++++----- Tests/test_imagefile.py | 5 +++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/PIL/GifImagePlugin.py b/PIL/GifImagePlugin.py index 8db42e8e8..ed4915b9f 100644 --- a/PIL/GifImagePlugin.py +++ b/PIL/GifImagePlugin.py @@ -269,7 +269,7 @@ def _save(im, fp, filename): pass # write uncompressed file if im.mode in RAWMODE: - im_out = im + im_out = im.copy() else: # convert on the fly (EXPERIMENTAL -- I'm not sure PIL # should automatically convert images on save...) diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index 1aa8a36bc..be0b8417e 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -92,20 +92,20 @@ class TestFileGif(PillowTestCase): def roundtrip(im, *args, **kwargs): out = self.tempfile('temp.gif') - im.save(out, *args, **kwargs) + im.copy().save(out, *args, **kwargs) reloaded = Image.open(out) - return [im, reloaded] + return reloaded orig = "Tests/images/test.colors.gif" im = Image.open(orig) - self.assert_image_equal(*roundtrip(im)) - self.assert_image_equal(*roundtrip(im, optimize=True)) + self.assert_image_similar(im, roundtrip(im), 1) + self.assert_image_similar(im, roundtrip(im, optimize=True), 1) im = im.convert("RGB") # check automatic P conversion - reloaded = roundtrip(im)[1].convert('RGB') + reloaded = roundtrip(im).convert('RGB') self.assert_image_equal(im, reloaded) @unittest.skipUnless(netpbm_available(), "netpbm not available") diff --git a/Tests/test_imagefile.py b/Tests/test_imagefile.py index 5311b899f..bc81575b6 100644 --- a/Tests/test_imagefile.py +++ b/Tests/test_imagefile.py @@ -26,7 +26,7 @@ class TestImageFile(PillowTestCase): test_file = BytesIO() - im.save(test_file, format) + im.copy().save(test_file, format) data = test_file.getvalue() @@ -37,7 +37,8 @@ class TestImageFile(PillowTestCase): return im, imOut self.assert_image_equal(*roundtrip("BMP")) - self.assert_image_equal(*roundtrip("GIF")) + im1, im2 = roundtrip("GIF") + self.assert_image_similar(im1.convert('P'), im2, 1) self.assert_image_equal(*roundtrip("IM")) self.assert_image_equal(*roundtrip("MSP")) if "zip_encoder" in codecs: From b1e8a68df8e7c858c78b89681678396005a678dc Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 14 May 2015 09:57:56 +1000 Subject: [PATCH 2/2] When copying Image, copy ImagePalette as well --- PIL/Image.py | 3 ++- PIL/ImagePalette.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/PIL/Image.py b/PIL/Image.py index 37428ec30..8ef4969ef 100644 --- a/PIL/Image.py +++ b/PIL/Image.py @@ -509,7 +509,8 @@ class Image: new.im = im new.mode = im.mode new.size = im.size - new.palette = self.palette + if self.palette: + new.palette = self.palette.copy() if im.mode == "P" and not new.palette: from PIL import ImagePalette new.palette = ImagePalette.ImagePalette() diff --git a/PIL/ImagePalette.py b/PIL/ImagePalette.py index c6c05d162..b5f07ee61 100644 --- a/PIL/ImagePalette.py +++ b/PIL/ImagePalette.py @@ -34,6 +34,18 @@ class ImagePalette: (size != 0 and size != len(self.palette))): raise ValueError("wrong palette size") + def copy(self): + new = ImagePalette() + + new.mode = self.mode + new.rawmode = self.rawmode + if self.palette is not None: + new.palette = self.palette[:] + new.colors = self.colors.copy() + new.dirty = self.dirty + + return new + def getdata(self): """ Get palette contents in format suitable # for the low-level