在Google App Engine中操作图像
2009 2 20 10:50 AM 3231次查看
分类:Google App Engine 标签:Google App Engine, Python
由于GAE不允许浏览者上传文件到服务器,所以存放到数据库就成了不二选择。可喜的是,如果你只是存储和显示图片,甚至连图像API都不需要用到,直接当成db.Blob类型的数据来使用即可。而且由于Google的慷慨,数据库空间是不限的,你可以在数据库中存放任意大小的文件(不过有流量限制)。
GAE提供了一些图像API来操作图像,包括调整大小、旋转、水平翻转、垂直翻转、截取及自动调整色彩和对比度,支持的图像格式有:JPEG、PNG、GIF(包括动画格式)、BMP、TIFF和ICO 。
事实上,GAE提供的只是Python Imaging Library的部分API,功能很简单,但也很容易学。
如果你要在本地开发服务器上使用,需要先安装PIL,是个几百KB的小东西。如果是在Google的服务器上,则已经默认添加了该库的部分图像转换API。
这些图像API非常简单,在使用图像API的文档里有效果演示,再参考图像类文档和函数文档,就能掌握其用法了。
提2个注意点:
1.本地开发服务器里是没有im_feeling_lucky这个函数的(因为PIL里没有这个API)。
2.Image类里有个execute_transforms方法,只有执行这个方法后,对图像的操作才会有效(并且是在这个方法返回,而不是改变原图像)。使用这个方法是会单独算在配额里的。
而images模块则没有这个函数,每次调用它的函数,都会立即生效。
并且,它们的输出格式都只有PNG和JPEG两种,也就意味着不能生成动态的GIF图像。
下面来看个例子:
首先是上传图片,注意指定编码方式(enctype="multipart/form-data")和输入类型(input type="file"):
self.response.out.write("""
<form action="/sign" enctype="multipart/form-data" method="post">
<div><label>Message:</label></div>
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><label>Avatar:</label></div>
<div><input type="file" name="img"/></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
</body>
</html>""")
接着是存储图片:from google.appengine.api import images
class Guestbook(webapp.RequestHandler):
def post(self):
greeting = Greeting()
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get("content")
#转换图像为32×32像素,如果不转换的话,直接greeting.avatar = db.Blob(self.request.get("img"))就行了
avatar = images.resize(self.request.get("img"), 32, 32)
greeting.avatar = db.Blob(avatar)
greeting.put()
self.redirect('/')
然后生成图像链接:self.response.out.write("<div><img src='img?img_id=%s'></img>" %
greeting.key()) #直接使用key,无需设置index
self.response.out.write(' %s</div>' %
cgi.escape(greeting.content))
最后是输出图像:class Image (webapp.RequestHandler):
def get(self):
#根据key从数据库中取出图像
greeting = db.get(self.request.get("img_id"))
if greeting.avatar:
#设置输出格式为PNG
self.response.headers['Content-Type'] = "image/png"
self.response.out.write(greeting.avatar)
else:
#找不到图像,输出404错误
self.error(404)
这样,这个从上传到显示的代码就结束了,完整版本可以看Google的文档。当然,你还可以对其进行一些改进,例如存放到memcache中和静态化图像链接。
此外,Google已经增加了单次上传数据的限制(10MB),但db.Blob类型最大只能存储1MB数据,如果你有需求的话,可以弄10个db.BlobProperty类型的属性,将其分成10个部分存储,输出时再合并。不过从数据库里取那么大的实体,应该是很影响性能的。
最后给个上传图像的演示站点:http://keakon.appspot.com/image
2010年12月1日更新:
如果需要自己生成图像,可以使用PNGCanvas(功能并不完备)。
0条评论 你不来一发么↓