diff options
Diffstat (limited to 'sca-cpp/trunk/hosting/server/imgutil.py')
-rw-r--r-- | sca-cpp/trunk/hosting/server/imgutil.py | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/sca-cpp/trunk/hosting/server/imgutil.py b/sca-cpp/trunk/hosting/server/imgutil.py new file mode 100644 index 0000000000..b622c804d8 --- /dev/null +++ b/sca-cpp/trunk/hosting/server/imgutil.py @@ -0,0 +1,106 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Image processing functions +from StringIO import StringIO +try: + from PIL import Image + from PIL import ImageOps + from PIL import ExifTags +except: + Image = None +from base64 import b64encode, b64decode +from urllib import urlopen +from util import * +from sys import debug + +# Rotate image if needed +def rotateimg(img): + debug('imgutil.py::rotateimg') + if not hasattr(img, '_getexif'): + return img + exif = img._getexif() + if exif is None: + return img + for tag, value in exif.items(): + decoded = ExifTags.TAGS.get(tag, tag) + if decoded == 'Orientation': + if value == 3: return img.rotate(180) + if value == 6: return img.rotate(270) + if value == 8: return img.rotate(90) + return img + +# Convert image to a cropped thumbnail +def thumbnail(img, size): + def intsz(*nums): + return tuple(int(round(n)) for n in nums) + + class imgsz(object): + def __init__(self, pair): + self.width = float(pair[0]) + self.height = float(pair[1]) + self.aspect_ratio = self.width / self.height + self.size = intsz(self.width, self.height) + + osz = imgsz(img.size) + tsz = imgsz(size) + + if tsz.aspect_ratio > osz.aspect_ratio: + scale = tsz.width / osz.width + crop = imgsz((osz.width, tsz.height / scale)) + cut = (osz.height - crop.height) / 2 + img = img.crop(intsz(0, cut, crop.width, cut + crop.height)) + elif tsz.aspect_ratio < osz.aspect_ratio: + scale = tsz.height / osz.height + crop = imgsz((tsz.width / scale, osz.height)) + cut = (osz.width - crop.width) / 2 + img = img.crop(intsz(cut, 0, cut + crop.width, crop.height)) + + return img.resize(tsz.size, Image.ANTIALIAS) + +# Convert image URL to a 50x50 JPEG +def urlto50x50jpeg(url): + debug('imgutil.py::urlto50x50jpeg::url', url) + if Image is None: + return url + img = Image.open(StringIO(b64decode(url.split(',')[1])) if url.startswith('data:') else StringIO(urlopen(url).read())) + if img.size == (50, 50): + debug('imgutil.py::urlto50x50jpeg::res', url) + return url + thumb = thumbnail(rotateimg(img), (50, 50)) + obuf = StringIO() + thumb.save(obuf, 'JPEG') + res = 'data:image/jpeg;base64,' + b64encode(obuf.getvalue()).replace('\n', '') + debug('imgutil.py::urlto50x50jpeg::res', res) + return res; + +# Convert image to a 50x50 JPEG +def bufto50x50jpeg(buf): + debug('imgutil.py::bufto50x50jpeg') + if Image is None: + return '' + img = Image.open(StringIO(buf)) + if img.size == (50, 50): + debug('imgutil.py::urlto50x50jpeg::res', url) + return url + thumb = thumbnail(rotateimg(img), (50, 50)) + obuf = StringIO() + thumb.save(obuf, 'JPEG') + res = 'data:image/jpeg;base64,' + b64encode(obuf.getvalue()).replace('\n', '') + debug('imgutil.py::bufto50x50jpeg::res', res) + return res + |