"""
Provides tools (currently: only functions, not a real service) for image
processing.
"""
from cStringIO import StringIO
from PIL import Image
import hashlib
__all__ = ['resize', 'crop_and_resize']
# TODO: cache to file
cache = {}
def get_format(img):
if isinstance(img, basestring):
img = StringIO(img)
image = Image.open(img)
return image.format
[docs]def resize(orig, hsize):
cache_key = (hashlib.md5(orig).digest(), hsize, hsize)
if cache_key in cache:
return cache[cache_key]
if isinstance(orig, basestring):
orig = StringIO(orig)
image = Image.open(orig)
format = image.format
x, y = image.size
if x <= hsize:
orig.seek(0)
return orig.read()
x1 = hsize
y1 = int(1.0 * y * hsize / x)
image.thumbnail((x1, y1), Image.ANTIALIAS)
output = StringIO()
if format in ('GIF', 'PNG'):
image.save(output, "PNG")
else:
image.save(output, "JPEG")
converted = output.getvalue()
cache[cache_key] = converted
return converted
[docs]def crop_and_resize(orig, hsize, vsize=0):
if isinstance(orig, basestring):
orig = StringIO(orig)
if not vsize:
vsize = hsize
cache_key = (hashlib.md5(orig.read()).digest(), hsize, vsize)
orig.seek(0)
if cache_key in cache:
return cache[cache_key]
image = Image.open(orig)
format = image.format
# Compute cropping coordinates
x1 = y1 = 0
x2, y2 = image.size
w_ratio = 1.0 * x2 / hsize
h_ratio = 1.0 * y2 / vsize
if h_ratio > w_ratio:
y1 = int(y2 / 2 - hsize * w_ratio / 2)
y2 = int(y2 / 2 + vsize * w_ratio / 2)
else:
x1 = int(x2 / 2 - hsize * h_ratio / 2)
x2 = int(x2 / 2 + vsize * h_ratio / 2)
image = image.crop((x1, y1, x2, y2))
image.thumbnail((hsize, vsize), Image.ANTIALIAS)
output = StringIO()
if format in ('GIF', 'PNG'):
image.save(output, "PNG")
else:
image.save(output, "JPEG")
converted = output.getvalue()
cache[cache_key] = converted
return converted