[Python-modules-commits] [willow] 02/07: Import willow_0.4+dfsg.orig.tar.gz

Christopher Stuart Hoskin mans0954 at moszumanska.debian.org
Tue Feb 28 07:31:16 UTC 2017


This is an automated email from the git hooks/post-receive script.

mans0954 pushed a commit to branch master
in repository willow.

commit 8f9e2b644071e4cbbce8bf4cf64e94e05bde9270
Author: Christopher Hoskin <mans0954 at debian.org>
Date:   Mon Feb 27 20:45:14 2017 +0000

    Import willow_0.4+dfsg.orig.tar.gz
---
 docs/changelog.rst       |  7 ++++---
 docs/guide/save.rst      | 26 ++++++++++++++++++++++++++
 docs/reference.rst       |  4 ++--
 setup.py                 |  4 ++--
 tests/test_pillow.py     | 33 +++++++++++++++++++++++++++------
 tests/test_wand.py       | 23 +++++++++++++++++++++++
 willow/__init__.py       |  2 +-
 willow/plugins/pillow.py | 20 ++++++++++++++++----
 willow/plugins/wand.py   |  6 +++---
 9 files changed, 104 insertions(+), 21 deletions(-)

diff --git a/docs/changelog.rst b/docs/changelog.rst
index a3a9de5..c6c7d92 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -1,13 +1,14 @@
 Changelog
 =========
 
-0.4 (IN DEVELOPMENT)
+0.4 (05/10/2016)
 --------------------
 
+ - Support for image optimisation and saving progressive JPEG files
  - Added documentation
 
-0.3.1 (IN DEVELOPMENT)
-----------------------
+0.3.1 (16/05/2016)
+------------------
 
  - Fixed crash in the Pillow auto_orient operation when the image has an invalid Orientation EXIF Tag (Sigurdur J Eggertsson)
  - The ``auto_orient`` operation now catches all errors raised while reading EXIF data (Tomas Olander)
diff --git a/docs/guide/save.rst b/docs/guide/save.rst
index 1830297..59ee2ad 100644
--- a/docs/guide/save.rst
+++ b/docs/guide/save.rst
@@ -30,3 +30,29 @@ For example, to save an image with low quality:
 
     with open('low_quality.jpg', 'wb') as f:
         i.save_as_jpeg(f, quality=40)
+
+Progressive JPEGs
+-----------------
+
+By default, JPEG's are saved in the same format as their source file but you
+can force Willow to always save a "progressive" JPEG file by setting the
+``progressive`` keyword argument to ``True``:
+
+.. code-block:: python
+
+    with open('progressive.jpg', 'wb') as f:
+        i.save_as_jpeg(f, progressive=True)
+
+Image optimisation
+------------------
+
+:meth:`~Image.save_as_jpeg` and :meth:`~Image.save_as_png` both take an
+``optimize`` keyword that when set to true, will output an optimized image.
+
+.. code-block:: python
+
+    with open('optimized.jpg', 'wb') as f:
+        i.save_as_jpeg(f, optimize=True)
+
+This feature is currently only supported in the Pillow backend, if you use Wand
+this argument will be ignored.
diff --git a/docs/reference.rst b/docs/reference.rst
index 1e159b7..b83ef7d 100644
--- a/docs/reference.rst
+++ b/docs/reference.rst
@@ -186,7 +186,7 @@ Here's a full list of operations provided by Willow out of the box:
 
         faces = image.detect_faces()
 
-.. method:: save_as_jpeg(file, quality=85)
+.. method:: save_as_jpeg(file, quality=85, optimize=False)
 
     (Pillow/Wand only)
 
@@ -199,7 +199,7 @@ Here's a full list of operations provided by Willow out of the box:
         with open('out.jpg', 'wb') as f:
             image.save_as_jpeg(f)
 
-.. method:: save_as_png(file)
+.. method:: save_as_png(file, optimize=False)
 
     (Pillow/Wand only)
 
diff --git a/setup.py b/setup.py
index 4d2ab26..ffd359d 100644
--- a/setup.py
+++ b/setup.py
@@ -20,12 +20,12 @@ except ImportError:
 
 setup(
     name='Willow',
-    version='0.4a0',
+    version='0.4',
     description='A Python image library that sits on top of Pillow, Wand and OpenCV',
     author='Karl Hobley',
     author_email='karlhobley10 at gmail.com',
     url='',
-    packages=find_packages(),
+    packages=find_packages(exclude=['tests']),
     include_package_data=True,
     license='BSD',
     classifiers=[
diff --git a/tests/test_pillow.py b/tests/test_pillow.py
index 7376edb..7160f22 100644
--- a/tests/test_pillow.py
+++ b/tests/test_pillow.py
@@ -2,6 +2,8 @@ import unittest
 import io
 import imghdr
 
+from PIL import Image as PILImage
+
 from willow.image import JPEGImageFile, PNGImageFile, GIFImageFile
 from willow.plugins.pillow import _PIL_Image, PillowImage
 
@@ -33,6 +35,18 @@ class TestPillowOperations(unittest.TestCase):
         self.assertIsInstance(return_value, JPEGImageFile)
         self.assertEqual(return_value.f, output)
 
+    def test_save_as_jpeg_optimised(self):
+        unoptimised = self.image.save_as_jpeg(io.BytesIO())
+        optimised = self.image.save_as_jpeg(io.BytesIO(), optimize=True)
+
+        # Optimised image must be smaller than unoptimised image
+        self.assertTrue(optimised.f.tell() < unoptimised.f.tell())
+
+    def test_save_as_jpeg_progressive(self):
+        image = self.image.save_as_jpeg(io.BytesIO(), progressive=True)
+
+        self.assertTrue(PILImage.open(image.f).info['progressive'])
+
     def test_save_as_png(self):
         output = io.BytesIO()
         return_value = self.image.save_as_png(output)
@@ -42,6 +56,13 @@ class TestPillowOperations(unittest.TestCase):
         self.assertIsInstance(return_value, PNGImageFile)
         self.assertEqual(return_value.f, output)
 
+    def test_save_as_png_optimised(self):
+        unoptimised = self.image.save_as_png(io.BytesIO())
+        optimised = self.image.save_as_png(io.BytesIO(), optimize=True)
+
+        # Optimised image must be smaller than unoptimised image
+        self.assertTrue(optimised.f.tell() < unoptimised.f.tell())
+
     def test_save_as_gif(self):
         output = io.BytesIO()
         return_value = self.image.save_as_gif(output)
@@ -144,15 +165,15 @@ class TestPillowImageOrientation(unittest.TestCase):
         # Check that the red flower is in the bottom left
         # The JPEGs have compressed slightly differently so the colours won't be spot on
         colour = image.image.convert('RGB').getpixel((155, 282))
-        self.assertAlmostEqual(colour[0], 217, delta=10)
-        self.assertAlmostEqual(colour[1], 38, delta=11)
-        self.assertAlmostEqual(colour[2], 46, delta=13)
+        self.assertAlmostEqual(colour[0], 217, delta=25)
+        self.assertAlmostEqual(colour[1], 38, delta=25)
+        self.assertAlmostEqual(colour[2], 46, delta=25)
 
         # Check that the water is at the bottom
         colour = image.image.convert('RGB').getpixel((377, 434))
-        self.assertAlmostEqual(colour[0], 85, delta=11)
-        self.assertAlmostEqual(colour[1], 93, delta=12)
-        self.assertAlmostEqual(colour[2], 65, delta=11)
+        self.assertAlmostEqual(colour[0], 85, delta=25)
+        self.assertAlmostEqual(colour[1], 93, delta=25)
+        self.assertAlmostEqual(colour[2], 65, delta=25)
 
     def test_jpeg_with_orientation_1(self):
         with open('tests/images/orientation/landscape_1.jpg', 'rb') as f:
diff --git a/tests/test_wand.py b/tests/test_wand.py
index 6104019..adc7ed1 100644
--- a/tests/test_wand.py
+++ b/tests/test_wand.py
@@ -4,6 +4,8 @@ import imghdr
 
 from wand.color import Color
 
+from PIL import Image as PILImage
+
 from willow.image import JPEGImageFile, PNGImageFile, GIFImageFile
 from willow.plugins.wand import _wand_image, WandImage
 
@@ -35,6 +37,19 @@ class TestWandOperations(unittest.TestCase):
         self.assertIsInstance(return_value, JPEGImageFile)
         self.assertEqual(return_value.f, output)
 
+    @unittest.expectedFailure
+    def test_save_as_jpeg_optimised(self):
+        unoptimised = self.image.save_as_jpeg(io.BytesIO())
+        optimised = self.image.save_as_jpeg(io.BytesIO(), optimize=True)
+
+        # Optimised image must be smaller than unoptimised image
+        self.assertTrue(optimised.f.tell() < unoptimised.f.tell())
+
+    def test_save_as_jpeg_progressive(self):
+        image = self.image.save_as_jpeg(io.BytesIO(), progressive=True)
+
+        self.assertTrue(PILImage.open(image.f).info['progressive'])
+
     def test_save_as_png(self):
         output = io.BytesIO()
         return_value = self.image.save_as_png(output)
@@ -44,6 +59,14 @@ class TestWandOperations(unittest.TestCase):
         self.assertIsInstance(return_value, PNGImageFile)
         self.assertEqual(return_value.f, output)
 
+    @unittest.expectedFailure
+    def test_save_as_png_optimised(self):
+        unoptimised = self.image.save_as_png(io.BytesIO())
+        optimised = self.image.save_as_png(io.BytesIO(), optimize=True)
+
+        # Optimised image must be smaller than unoptimised image
+        self.assertTrue(optimised.f.tell() < unoptimised.f.tell())
+
     def test_save_as_gif(self):
         output = io.BytesIO()
         return_value = self.image.save_as_gif(output)
diff --git a/willow/__init__.py b/willow/__init__.py
index ec6f52b..10ed687 100644
--- a/willow/__init__.py
+++ b/willow/__init__.py
@@ -27,4 +27,4 @@ def setup():
 setup()
 
 
-__version__ = '0.4a0'
+__version__ = '0.4'
diff --git a/willow/plugins/pillow.py b/willow/plugins/pillow.py
index bb1f90a..6bb0000 100644
--- a/willow/plugins/pillow.py
+++ b/willow/plugins/pillow.py
@@ -57,18 +57,30 @@ class PillowImage(Image):
         return PillowImage(self.image.crop(rect))
 
     @Image.operation
-    def save_as_jpeg(self, f, quality=85):
+    def save_as_jpeg(self, f, quality=85, optimize=False, progressive=False):
         if self.image.mode in ['1', 'P']:
             image = self.image.convert('RGB')
         else:
             image = self.image
 
-        image.save(f, 'JPEG', quality=quality)
+        # Pillow only checks presence of optimize kwarg, not its value
+        kwargs = {}
+        if optimize:
+            kwargs['optimize'] = True
+        if progressive:
+            kwargs['progressive'] = True
+
+        image.save(f, 'JPEG', quality=quality, **kwargs)
         return JPEGImageFile(f)
 
     @Image.operation
-    def save_as_png(self, f):
-        self.image.save(f, 'PNG')
+    def save_as_png(self, f, optimize=False):
+        # Pillow only checks presence of optimize kwarg, not its value
+        kwargs = {}
+        if optimize:
+            kwargs['optimize'] = True
+
+        self.image.save(f, 'PNG', **kwargs)
         return PNGImageFile(f)
 
     @Image.operation
diff --git a/willow/plugins/wand.py b/willow/plugins/wand.py
index 630c35c..482bc74 100644
--- a/willow/plugins/wand.py
+++ b/willow/plugins/wand.py
@@ -60,15 +60,15 @@ class WandImage(Image):
         return clone
 
     @Image.operation
-    def save_as_jpeg(self, f, quality=85):
-        with self.image.convert('jpeg') as converted:
+    def save_as_jpeg(self, f, quality=85, optimize=False, progressive=False):
+        with self.image.convert('pjpeg' if progressive else 'jpeg') as converted:
             converted.compression_quality = quality
             converted.save(file=f)
 
         return JPEGImageFile(f)
 
     @Image.operation
-    def save_as_png(self, f):
+    def save_as_png(self, f, optimize=False):
         with self.image.convert('png') as converted:
             converted.save(file=f)
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/willow.git



More information about the Python-modules-commits mailing list