Skip to content

Instantly share code, notes, and snippets.

@jawache
Created March 20, 2013 17:24
Show Gist options
  • Save jawache/5206573 to your computer and use it in GitHub Desktop.
Save jawache/5206573 to your computer and use it in GitHub Desktop.
Using PIL on Google App Engine to manipulate images and store inthe blobstore
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en-gb">
<head>
<title>Hello World</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
# -*- coding: utf-8 -*-
"""
__author__ = "Asim Hussain"
__copyright__ = "Copyright 2012, RT Sports Ltd. All Rights Reserved"
"""
import logging
LOGGER = logging.getLogger(__name__)
from django import forms
class PhotoForm(forms.Form):
name = forms.CharField(required=True)
from google.appengine.ext import blobstore
from google.appengine.ext import db
class LogoItem(db.Model):
name = db.StringProperty()
original = blobstore.BlobReferenceProperty()
enhanced = blobstore.BlobReferenceProperty()
transparent = blobstore.BlobReferenceProperty()
{% extends "base.html" %}
{% block content %}
<style type="text/css">
h1 {
font-family: "Helvetica Neue Light", sans-serif;
}
body {
background-color: black;
color: white;;
}
</style>
<h1>Original Logo</h1>
<img src="{{ original }}"/>
<h1>Transparent Logo</h1>
<img src="{{ trans }}"/>
<h1>Enhanced Transparent Logo</h1>
<img src="{{ enhanced }}"/>
<h1>Enhanced Transparent Thumbnail Logo</h1>
<img src="{{ thumbnail }}"/>
{% endblock %}
{% extends "base.html" %}
{% block content %}
<h1>Upload Photo</h1>
{% if upload_error %}
<div class="error">{{ upload_error }}</div>
{% endif %}
<form action="{{ upload_url }}" method="post"
enctype="multipart/form-data">
{% csrf_token %}
<ul>
{{ form.as_ul }}
<li><input type="file" name="photo"/></li>
<li><input type="submit"/></li>
</ul>
</form>
{% endblock %}
import logging
import cStringIO
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
from google.appengine.api import files, images
from google.appengine.api.images import get_serving_url, Image
from google.appengine.ext import blobstore, db
from PIL import Image as PILImage
from core.models import LogoItem
from core.forms import PhotoForm
from core.utils import get_uploads
def success(request):
key_name = request.GET.get("key_name")
key = db.Key.from_path('LogoItem', key_name)
logoitem = db.get(key)
context = dict(
original = get_serving_url(logoitem.original),
enhanced = get_serving_url(logoitem.enhanced),
thumbnail = get_serving_url(logoitem.enhanced, crop=True, size=32),
trans = get_serving_url(logoitem.enhanced)
)
return render_to_response("success.html",
context,
RequestContext(request))
def upload_photo(request):
if request.method == 'POST':
photo_blobs = get_uploads(request, field_name="photo", populate_post=True)
form = PhotoForm(request.POST)
if form.is_valid() and len(photo_blobs) == 1:
name = form.cleaned_data['name']
logo = photo_blobs[0]
im = PILImage.open(logo.open())
im = im.convert("RGBA")
pixdata = im.load()
for y in xrange(im.size[1]):
for x in xrange(im.size[0]):
if pixdata[x, y] == (255, 255, 255, 255):
pixdata[x, y] = (255, 255, 255, 0)
buf = cStringIO.StringIO()
im.save(buf, "PNG")
data = buf.getvalue()
# Save transparent image back to blobstore
transparent_file = files.blobstore.create(mime_type='image/png')
with files.open(transparent_file, 'a') as f:
f.write(data)
files.finalize(transparent_file)
# Enhance Transparent Logo
img = Image(blob_key=files.blobstore.get_blob_key(transparent_file))
img.im_feeling_lucky()
enhanced = img.execute_transforms(output_encoding=images.PNG)
# Save enhanced image back to blob store
enhanced_file = files.blobstore.create(mime_type='image/png')
with files.open(enhanced_file, 'a') as f:
f.write(enhanced)
files.finalize(enhanced_file)
photo_item = LogoItem(key_name=name,
name=name,
original=logo,
enhanced=files.blobstore.get_blob_key(enhanced_file),
transparent=files.blobstore.get_blob_key(transparent_file))
photo_item.put()
return redirect("success/?key_name=%s" % name)
#ok, not valid
if len(photo_blobs) == 0:
#the file input is missing
request.session['upload_error'] = "Photo is required"
#save the post data in the session to be able to present errors after redirect
request.session['upload_form_post'] = request.POST
return HttpResponseRedirect(reverse("core.views.upload_photo"))
elif request.session.has_key('upload_form_post'):
form = PhotoForm(request.session['upload_form_post'])
del request.session['upload_form_post']
else:
form = PhotoForm()
params = {
'upload_url': blobstore.create_upload_url(reverse("core.views.upload_photo")),
'form': form,
'upload_error': request.session.pop('upload_error', None)
}
return render_to_response("upload_photo.html",
params,
RequestContext(request))
def exception_test(request):
logging.debug('Debug log')
logging.warn('Warn log')
logging.error('Error log')
raise Exception()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment