[Pkg-mozext-commits] [adblock-plus] 09/41: Issue 1897 - Compress auto-generated images with pngout
David Prévot
taffit at moszumanska.debian.org
Wed Mar 18 18:21:37 UTC 2015
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository adblock-plus.
commit 992c2cf5c54b5f94c633b7c058f75627c317d3a7
Author: Sebastian Noack <sebastian at adblockplus.org>
Date: Wed Jan 28 20:10:49 2015 +0100
Issue 1897 - Compress auto-generated images with pngout
---
imageCompression.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++
imageConversion.py | 12 ++++----
2 files changed, 89 insertions(+), 5 deletions(-)
diff --git a/imageCompression.py b/imageCompression.py
new file mode 100644
index 0000000..6ffe46a
--- /dev/null
+++ b/imageCompression.py
@@ -0,0 +1,82 @@
+# coding: utf-8
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import subprocess
+import threading
+import errno
+import logging
+from StringIO import StringIO
+
+try:
+ from PIL import Image
+except ImportError:
+ import Image
+
+use_pngout = True
+
+class Pngout:
+ def __init__(self, image):
+ args = ['pngout', '-', '-', '-q']
+
+ # Preserve mode for grayscale images. pngout tends to convert
+ # everyting to palette. However, the toolbar icons for Safari
+ # require the grayscale+alpha mode. Moreover, pngout seems to
+ # generate smaller files when forced to preserve grayscale mode.
+ if image.mode == 'LA' and any(px < 0xff for px in image.split()[1].getdata()):
+ args.append('-c4') # grayscale+alpha
+ elif Image.getmodebase(image.mode) == 'L':
+ args.append('-c0') # grayscale
+
+ self._pngout = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+
+ # Writing will block when the buffer is full until we read more data
+ # from the output. Reading the output will block when the input isn't
+ # complete yet. So we have to use threads to do both at the same time.
+ self._thread = threading.Thread(target=self._run_thread, args=(image,))
+ self._thread.daemon = True
+ self._thread.start()
+
+ # This is supposed to be a file-like object, reading the compressed PNG file.
+ # So proxy methods like read() to the stdout of the underlying subprocess.
+ def __getattr__(self, name):
+ return getattr(self._pngout.stdout, name)
+
+ def _run_thread(self, image):
+ image.save(self._pngout.stdin, 'PNG')
+ self._pngout.stdin.close()
+
+ def close(self):
+ self._thread.join()
+ self._pngout.stdout.close()
+ self._pngout.wait()
+
+class ImageCompressor:
+ use_pngout = True
+
+ def make_uncompressed_file(self, image, filename):
+ file = StringIO()
+ file.name = filename # Set the 'name' attribute, so that PIL can determine
+ # the correct image type based on the file extension
+ image.save(file)
+ file.seek(0)
+
+ return file
+
+ def make_file(self, image, filename):
+ if self.use_pngout and os.path.splitext(filename)[1].lower() == '.png':
+ try:
+ return Pngout(image)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
+
+ logging.warning("Couldn't find 'pngout', can't compress images")
+ self.use_pngout = False
+
+ return self.make_uncompressed_file(image, filename)
+
+image_to_file = ImageCompressor().make_file
diff --git a/imageConversion.py b/imageConversion.py
index e56dae7..021a762 100644
--- a/imageConversion.py
+++ b/imageConversion.py
@@ -6,7 +6,6 @@
import os
import re
-from StringIO import StringIO
try:
from PIL import Image
@@ -15,6 +14,8 @@ except ImportError:
import Image
import ImageOps
+from imageCompression import image_to_file
+
def get_alpha(image):
if image.mode in ('RGBA', 'LA'):
return image.split()[image.getbands().index('A')]
@@ -95,7 +96,8 @@ def convertImages(params, files):
args = re.split(r'\s*,\s*', args) if args else ()
image = globals()['filter_' + filter](image, baseDir, *args)
- f = StringIO()
- f.name = filename
- image.save(f)
- files[filename] = f.getvalue()
+ file = image_to_file(image, filename)
+ try:
+ files[filename] = file.read()
+ finally:
+ file.close()
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/adblock-plus.git
More information about the Pkg-mozext-commits
mailing list