Transpose processor now supports auto EXIF orientation.

Replaced calls to Image.open with an open_image utility function.
The open_image utility calls Image.open, but then wraps the opened Image's
copy method with a version that preserves EXIF data. This allows an
ImageSpec to copy the original image, yet still provide all the original
image's exif data to the processor pipeline.
This commit is contained in:
Eric Eldredge 2011-09-24 23:09:49 -04:00
parent c694ba644f
commit f570bd0d7f
3 changed files with 30 additions and 6 deletions

View file

@ -2,7 +2,7 @@ import os
import datetime
from StringIO import StringIO
from imagekit.lib import *
from imagekit.utils import img_to_fobj, get_spec_files
from imagekit.utils import img_to_fobj, get_spec_files, open_image
from imagekit.processors import ProcessorPipeline
from django.conf import settings
from django.core.files.base import ContentFile
@ -93,7 +93,7 @@ def _get_suggested_extension(name, format):
class _ImageSpecFileMixin(object):
def _process_content(self, filename, content):
img = Image.open(content)
img = open_image(content)
original_format = img.format
img = self.field.process(img, self)
@ -138,7 +138,7 @@ class ImageSpecFile(_ImageSpecFileMixin):
if lazy:
img = self._img
if not img and self.storage.exists(self.name):
img = Image.open(self.file)
img = open_image(self.file)
if not img and self.source_file:
# Process the original image file
try:

View file

@ -224,11 +224,9 @@ class Transpose(ImageProcessor):
def process(self, img):
if self.AUTO in self.methods:
raise Exception("AUTO is not yet supported. Sorry!")
try:
orientation = img._getexif()[0x0112]
ops = self._EXIF_ORIENTATION_STEPS[orientation]
print 'GOT %s >>>> %s' % (orientation, ops)
except AttributeError:
ops = []
else:

View file

@ -1,6 +1,9 @@
""" ImageKit utility functions """
import tempfile
import tempfile, types
from django.utils.functional import wraps
from lib import Image
def img_to_fobj(img, format, **kwargs):
tmp = tempfile.TemporaryFile()
@ -20,3 +23,26 @@ def get_spec_files(instance):
if isinstance(value, ImageSpecFile):
spec_files.append(value)
return spec_files
def open_image(target):
img = Image.open(target)
img.copy = types.MethodType(_wrap_copy(img.copy), img, img.__class__)
return img
def _wrap_copy(f):
@wraps(f)
def copy(self):
img = f()
try:
img.app = self.app
except AttributeError:
pass
try:
img._getexif = self._getexif
except AttributeError:
pass
return img
return copy