Base64在AppEngine上编码二进制上传的数据 [英] Base64 encode binary uploaded data on the AppEngine

查看:139
本文介绍了Base64在AppEngine上编码二进制上传的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试使用Base64编码来自用户的图像数据(在这种情况下是可信的管理员),以便跳过对BlobStore的调用次数尽可能多。每次我尝试对它进行编码时,我收到一条错误:

 上传图像时出错:'ascii'编解码器无法解码位置0中的字节0x89:序号不在范围内(128)

我已经google了错误不太重要的部分),并发现它可能与Unicode(?)有关。模板部分只是一个基本的上传表单,而处理程序包含以下代码:

  def post(self,id): 
logging.info(ImagestoreHandler#post%s,self.request.path)
fileupload = self.request.POST.get(file,None)
如果fileupload为无:return self.error(400)

content_type = fileupload.type或getContentType(fileupload.filename)
如果content_type为None:
self.error(400)
self.response.headers ['Content-Type'] ='text / plain'
self.response.out.write(不支持的图像类型:+ fileupload.filename)
return
logging.debug(文件上传:%s,mime类型:%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
除了异常,err:
logging.exception(存储映像时出错)
self.error(400)
self.response.headers ['Content-Type'] ='text / plain'
self.response .out.write(上传图像:+ str(err))
return
#self.redirect(urlBase%img.key())#dummy redirect对于非AJAX客户端是可以接受的,对于真正的REST客户端,
#位置标题应该是可以接受的,但是AJAX请求
#可能无法访问位置标题,所以我们将用
#编写一个200响应,新的URL响应体:

acceptType = self.request.accept.best_match(listRenderers.keys())
out = self.response.out
如果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 ['Cont ent-Type'] ='text / html'
out.write('< a href =%s>%s< / a>'%(img_url,img_name))

def _store_image(self,name,file,content_type):
POST处理程序委托这个方法来实际映像存储;作为
的结果,替代实现可能容易地覆盖存储
机制,而不重写相同的内容类型处理。

此方法返回一个文件名和图像URL的元组。

img_enc = base64.b64encode(file.read())
img_enc_struct =数据:%s; base64,%s%(content_type,img_enc)

img = Image(name = name,data = img_enc_struct)
img.put()
logging .info(保存的图像到密钥%s,img.key())
return(str(img.name),img.key())
pre>

我的图像模型:

  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的分支分支这里

解决方案

您的商店图片代码可能就是这样....

  img = Image(name = name,data = file.read())
img.put()
return(str(img.name),img.key())

执行二进制数据的base64encode可能会增加数据本身的大小并增加cpu编码和解码时间。



和Blobstore使用与数据存储相同的存储sturcuture,所以它只是让
使用文件上传存储下载更容易。


I've been trying to Base64 encode image data from the user (in this case a trusted admin) in order to skip as many calls to the BlobStore as I possibly can. Every time I attempt to encode it, I recieve an error saying:

Error uploading image: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)

I've googled the error (the less significant parts) and found that it may have something to do with Unicode (?). The template portion is just a basic upload form, while the handler contains the following code:

  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() )

My image model:

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)

Any help is greatly appreciated. This code, minus my image encoding in _store_image, comes from the blooger branch of gvdent here.

解决方案

your store image code could be like this....

img = Image( name=name, data=file.read() )
img.put()
return ( str(img.name), img.key() )

doing base64encode of binary data may increase the size of data itself and increase the cpu encoding and decoding time.

and Blobstore uses the same storage sturcuture as datastore, so it is just making easier to use file upload store download.

这篇关于Base64在AppEngine上编码二进制上传的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆