Base64在AppEngine上编码二进制上传的数据
问题描述:
我一直在尝试Base64编码来自用户的图像数据(在这种情况下是受信任的管理员),以便尽可能多地跳过对BlobStore的调用。每次我试图对它进行编码,我收到一条错误消息:(?)Base64在AppEngine上编码二进制上传的数据
Error uploading image: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)
我GOOGLE了错误(少显著的部分),并发现它可能有一些做使用Unicode。模板部分仅仅是一个基本的上传表单,而处理程序包含以下代码:
def post(self,id):
logging.info("ImagestoreHandler#post %s", self.request.path)
fileupload = self.request.POST.get("file",None)
if fileupload is None : return self.error(400)
content_type = fileupload.type or getContentType(fileupload.filename)
if content_type is None:
self.error(400)
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("Unsupported image type: " + fileupload.filename)
return
logging.debug("File upload: %s, mime type: %s", fileupload.filename, content_type)
try:
(img_name, img_url) = self._store_image(
fileupload.filename, fileupload.file, content_type)
self.response.headers['Location'] = img_url
ex=None
except Exception, err:
logging.exception("Error while storing image")
self.error(400)
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("Error uploading image: " + str(err))
return
#self.redirect(urlBase % img.key()) #dummy redirect is acceptable for non-AJAX clients,
# location header should be acceptable for true REST clients, however AJAX requests
# might not be able to access the location header so we'll write a 200 response with
# the new URL in the response body:
acceptType = self.request.accept.best_match(listRenderers.keys())
out = self.response.out
if acceptType == 'application/json':
self.response.headers['Content-Type'] = 'application/json'
out.write('{"name":"%s","href":"%s"}' % (img_name, img_url))
elif re.search('html|xml', acceptType):
self.response.headers['Content-Type'] = 'text/html'
out.write('<a href="%s">%s</a>' % (img_url, img_name))
def _store_image(self, name, file, content_type):
"""POST handler delegates to this method for actual image storage; as
a result, alternate implementation may easily override the storage
mechanism without rewriting the same content-type handling.
This method returns a tuple of file name and image URL."""
img_enc = base64.b64encode(file.read())
img_enc_struct = "data:%s;base64,%s" % (content_type, img_enc)
img = Image(name=name, data=img_enc_struct)
img.put()
logging.info("Saved image to key %s", img.key())
return (str(img.name), img.key())
我的图像模型:
from google.appengine.ext import db
class Image(db.Model):
name = db.StringProperty(required=True)
data = db.TextProperty(required=True)
created = db.DateTimeProperty(auto_now_add=True)
owner = db.UserProperty(auto_current_user_add=True)
任何帮助是极大的赞赏。这个代码,在_store_image中减去我的图像编码,来自gvdent here的blooger分支。
答
店面形象代码可能是这样的....
img = Image(name=name, data=file.read())
img.put()
return (str(img.name), img.key())
做的二进制数据base64encode可能会增加数据本身的大小并增加CPU的编码和解码的时间。
和Blobstore使用与数据存储相同的存储结构,所以它只是使 使用文件上传存储下载更容易。
你能展示你的图片模型吗? – iamgopal 2010-07-12 02:51:59
我更新了它以包含图像模型。 – Matt 2010-07-12 03:15:09
该错误与Unicode没有任何关系; Python正在试图将你的二进制数据编码为一个字符串,并假定它是ASCII,然后对大于127的字节进行扼流,因为它们不是有效的ASCII。确实,在处理utf-8数据时(也使用第8位),通常会遇到此错误,但它并不是排他性的。 – geoffspear 2010-07-12 03:35:53