2010-07-12 54 views
2

我一直在嘗試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分支。

+0

你能展示你的圖片模型嗎? – iamgopal 2010-07-12 02:51:59

+0

我更新了它以包含圖像模型。 – Matt 2010-07-12 03:15:09

+0

該錯誤與Unicode沒有任何關係; Python正在試圖將你的二進制數據編碼爲一個字符串,並假定它是ASCII,然後對大於127的字節進行扼流,因爲它們不是有效的ASCII。確實,在處理utf-8數據時(也使用第8位),通常會遇到此錯誤,但它並不是排他性的。 – geoffspear 2010-07-12 03:35:53

回答

4

店面形象代碼可能是這樣的....

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

做的二進制數據base64encode可能會增加數據本身的大小並增加CPU的編碼和解碼的時間。

和Blobstore使用與數據存儲相同的存儲結構,所以它只是使 使用文件上傳存儲下載更容易。

相關問題