ほんじゃらねっと

ダイエット中プログラマのブログ

Google App Engine で画像を正方形にcropして保存

こちらのRuby版を参考にしました。
http://d.hatena.ne.jp/tohtas/20100221/1266778938


サムネイル等で画像を縮小してから正方形にcropする。


image_api.py

from google.appengine.api import images
def resize_image(image_data, width, height):
"""画像のリサイズのみ"""
image = images.Image(image_data)
image.resize(width, height)
return image.execute_transforms()
def crop_image(image_data, width, height):
"""画像をリサイズしてcropする"""
image = images.Image(image_data)
org_width = float(image.width)
org_height = float(image.height)
scale_w = width / org_width
scale_h = height / org_height
scale = scale_h if scale_w < scale_h else scale_w
thumb_width = int(org_width * scale)
thumb_height = int(org_height * scale)
image.resize(thumb_width, thumb_height)
x = (thumb_width - width) / 2.0
y = (thumb_height - height) / 2.0
image.crop(x/thumb_width, y/thumb_height, 1.0-(x/thumb_width), 1.0-(y/thumb_height))
return image.execute_transforms()


モデル例

...
class UserInfo(db.Model):
...
icon = db.BlobProperty()
icon24 = db.BlobProperty()
icon_mime = db.StringProperty()


保存方法

...
import image_api
...
class UserIconUpdateRequestHandler(webapp.RequestHandler):
def post(self):
# HTML側でファイル入力フィールドのnameにuser_iconと指定
icon = self.request.get("user_icon")
icon_mime = None
if icon:
icon_mime = self.request.body_file.vars['user_icon'].headers['content-type']
userinfo = UserInfo()
icon48 = img.crop_image(icon, 48, 48)
userinfo.icon = db.Blob(icon48)
icon24 = img.resize_image(icon, 24, 24)
userinfo.icon24 = db.Blob(icon24)
userinfo.icon_mime = icon_mime
userinfo.put()
...


画像出力方法(imgタグのsrc属性で呼び出す)

...
class UserIconRequestHandler(webapp.RequestHandler):
def get(self):
# userinfo 取得
...
if userinfo.icon is None:
self.redirect("/img/default_icon.png?%s" % settings.VERSION)
return
self.response.content_type = userinfo.icon_mime
self.response.out.write(userinfo.icon)