[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