diff --git a/requirements.txt b/requirements.txt index 45cc767..18306a3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,5 @@ clint Jinja2 Markdown Pillow +pilkit pytest diff --git a/setup.py b/setup.py index f3c6157..319d78c 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ import os from setuptools import setup, find_packages -requires = ['argh', 'clint', 'jinja2', 'Markdown'] +requires = ['argh', 'clint', 'jinja2', 'Markdown', 'pilkit'] try: from PIL import Image, ImageOps # NOQA diff --git a/sigal/gallery.py b/sigal/gallery.py index 62f93ac..ca4a6bf 100644 --- a/sigal/gallery.py +++ b/sigal/gallery.py @@ -244,14 +244,14 @@ def process_image(filepath, outpath, settings): if settings['keep_orig']: img.save(join(outpath, settings['orig_dir'], filename), - **settings['jpg_options']) + options=settings['jpg_options']) img.resize(settings['img_size']) if settings['copyright']: img.add_copyright(settings['copyright']) - img.save(outname, **settings['jpg_options']) + img.save(outname, options=settings['jpg_options']) if settings['make_thumbs']: thumb_name = join(outpath, get_thumb(settings, filename)) diff --git a/sigal/image.py b/sigal/image.py index 70ebd4f..486bb68 100644 --- a/sigal/image.py +++ b/sigal/image.py @@ -24,10 +24,9 @@ from __future__ import division import logging import os -import sys -from exceptions import IOError from PIL import Image as PILImage -from PIL import ImageDraw, ImageOps, ImageFile +from PIL import ImageDraw, ImageOps +from pilkit.utils import save_image # EXIF specs Orientation constant EXIF_ORIENTATION_TAG = 274 @@ -47,10 +46,7 @@ class Image(object): self.filename = filename self.imgname = os.path.split(filename)[1] self.logger = logging.getLogger(__name__) - - with open(filename, 'rb') as fp: - self.img = PILImage.open(fp) - self.img.load() + self.img = PILImage.open(filename) # Try to read exif metadata. This can fail if: # - the image does not have exif (png files) -> AttributeError @@ -68,25 +64,14 @@ class Image(object): if rotation: self.img = self.img.rotate(rotation) - def save(self, filename, **kwargs): + def save(self, filename, format='JPEG', options=None, autoconvert=True): """Save the image. - Pass a dict with PIL options (quality, optimize, progressive). PIL can - have problems saving large JPEGs if MAXBLOCK isn't big enough, So if - we have a problem saving, we temporarily increase it. See - http://github.com/jdriscoll/django-imagekit/issues/91 + Pass a dict with PIL options (quality, optimize, progressive). """ - try: - with quiet(): - self.img.save(filename, "JPEG", **kwargs) - except IOError: - old_maxblock = ImageFile.MAXBLOCK - ImageFile.MAXBLOCK = self.img.size[0] * self.img.size[1] - try: - self.img.save(filename, "JPEG", **kwargs) - finally: - ImageFile.MAXBLOCK = old_maxblock + save_image(self.img, filename, format, options=options, + autoconvert=autoconvert) def resize(self, size): """Resize the image. @@ -128,20 +113,3 @@ class Image(object): self.img.thumbnail(box, PILImage.ANTIALIAS) self.img.save(filename, quality=quality) - - -class quiet(object): - """A context manager for suppressing the stderr activity of PIL's C - libraries. Based on http://stackoverflow.com/a/978264/155370 - - """ - def __enter__(self): - self.stderr_fd = sys.__stderr__.fileno() - self.null_fd = os.open(os.devnull, os.O_RDWR) - self.old = os.dup(self.stderr_fd) - os.dup2(self.null_fd, self.stderr_fd) - - def __exit__(self, *args, **kwargs): - os.dup2(self.old, self.stderr_fd) - os.close(self.null_fd) - os.close(self.old)