diff --git a/PIL/JpegImagePlugin.py b/PIL/JpegImagePlugin.py index 63fd0dcbf..e216fa06d 100644 --- a/PIL/JpegImagePlugin.py +++ b/PIL/JpegImagePlugin.py @@ -688,12 +688,14 @@ def _save(im, fp, filename): progressive = info.get("progressive", False) or\ info.get("progression", False) + optimize = info.get("optimize", False) + # get keyword arguments im.encoderconfig = ( quality, progressive, info.get("smooth", 0), - "optimize" in info, + optimize, info.get("streamtype", 0), dpi[0], dpi[1], subsampling, @@ -707,7 +709,7 @@ def _save(im, fp, filename): # channels*size, this is a value that's been used in a django patch. # https://github.com/matthewwithanm/django-imagekit/issues/50 bufsize = 0 - if "optimize" in info or progressive: + if optimize or progressive: # keep sets quality to 0, but the actual value may be high. if quality >= 95 or quality == 0: bufsize = 2 * im.size[0] * im.size[1] diff --git a/PIL/PngImagePlugin.py b/PIL/PngImagePlugin.py index 18deec546..4975d5598 100644 --- a/PIL/PngImagePlugin.py +++ b/PIL/PngImagePlugin.py @@ -696,15 +696,10 @@ def _save(im, fp, filename, chunk=putchunk, check=0): mode = "%s;%d" % (mode, bits) # encoder options - if "dictionary" in im.encoderinfo: - dictionary = im.encoderinfo["dictionary"] - else: - dictionary = b"" - - im.encoderconfig = ("optimize" in im.encoderinfo, + im.encoderconfig = (im.encoderinfo.get("optimize", False), im.encoderinfo.get("compress_level", -1), im.encoderinfo.get("compress_type", -1), - dictionary) + im.encoderinfo.get("dictionary", b"")) # get the corresponding PNG mode try: diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index 0ae82fac2..43eed48d7 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -126,9 +126,12 @@ class TestFileJpeg(PillowTestCase): def test_optimize(self): im1 = self.roundtrip(hopper()) - im2 = self.roundtrip(hopper(), optimize=1) + im2 = self.roundtrip(hopper(), optimize=0) + im3 = self.roundtrip(hopper(), optimize=1) self.assert_image_equal(im1, im2) + self.assert_image_equal(im1, im3) self.assertGreaterEqual(im1.bytes, im2.bytes) + self.assertGreaterEqual(im1.bytes, im3.bytes) def test_optimize_large_buffer(self): # https://github.com/python-pillow/Pillow/issues/148 @@ -139,9 +142,14 @@ class TestFileJpeg(PillowTestCase): def test_progressive(self): im1 = self.roundtrip(hopper()) - im2 = self.roundtrip(hopper(), progressive=True) - self.assert_image_equal(im1, im2) - self.assertGreaterEqual(im1.bytes, im2.bytes) + im2 = self.roundtrip(hopper(), progressive=False) + im3 = self.roundtrip(hopper(), progressive=True) + self.assertFalse(im1.info.get("progressive")) + self.assertFalse(im2.info.get("progressive")) + self.assertTrue(im3.info.get("progressive")) + + self.assert_image_equal(im1, im3) + self.assertGreaterEqual(im1.bytes, im3.bytes) def test_progressive_large_buffer(self): f = self.tempfile('temp.jpg') diff --git a/docs/handbook/image-file-formats.rst b/docs/handbook/image-file-formats.rst index 33728e094..459cb75d8 100644 --- a/docs/handbook/image-file-formats.rst +++ b/docs/handbook/image-file-formats.rst @@ -219,20 +219,20 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options: image quality. **optimize** - If present, indicates that the encoder should make an extra pass over the - image in order to select optimal encoder settings. + If present and true, indicates that the encoder should make an extra pass + over the image in order to select optimal encoder settings. **progressive** - If present, indicates that this image should be stored as a progressive - JPEG file. + If present and true, indicates that this image should be stored as a + progressive JPEG file. **dpi** A tuple of integers representing the pixel density, ``(x,y)``. **icc_profile** - If present, the image is stored with the provided ICC profile. If - this parameter is not provided, the image will be saved with no - profile attached. To preserve the existing profile:: + If present and true, the image is stored with the provided ICC profile. + If this parameter is not provided, the image will be saved with no profile + attached. To preserve the existing profile:: im.save(filename, 'jpeg', icc_profile=im.info.get('icc_profile')) @@ -399,9 +399,9 @@ chunks is limited to ``PngImagePlugin.MAX_TEXT_MEMORY``, defaulting to The :py:meth:`~PIL.Image.Image.save` method supports the following options: **optimize** - If present, instructs the PNG writer to make the output file as small as - possible. This includes extra processing in order to find optimal encoder - settings. + If present and true, instructs the PNG writer to make the output file as + small as possible. This includes extra processing in order to find optimal + encoder settings. **transparency** For ``P``, ``L``, and ``RGB`` images, this option controls what @@ -615,8 +615,7 @@ format are currently undocumented. The :py:meth:`~PIL.Image.Image.save` method supports the following options: **lossless** - If present, instructs the WEBP writer to use lossless - compression. + If present and true, instructs the WEBP writer to use lossless compression. **quality** Integer, 1-100, Defaults to 80. Sets the quality level for