2010-07-12 4 views
2

J'ai essayé de Base64 encoder des données d'image de l'utilisateur (dans ce cas un administrateur de confiance) afin de passer le plus d'appels possible au BlobStore. Chaque fois que je tente de le coder, je reçois une erreur disant: (?)Base64 encoder des données téléchargées binaires sur AppEngine

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

J'ai googlé l'erreur (les parties moins importantes) et a constaté que cela a quelque chose à voir avec Unicode. La partie de modèle est juste une forme de téléchargement de base, tandis que le gestionnaire contient le code suivant:

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

Mon modèle d'image:

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) 

Toute aide est grandement appréciée. Ce code, moins mon image codée dans _store_image, provient de la branche blooger de gvdent here.

+0

pouvez-vous montrer votre modèle d'image? – iamgopal

+0

Je l'ai mis à jour pour inclure également le modèle d'image. – Matt

+0

L'erreur n'a rien à voir avec Unicode; Python essaie de coder vos données binaires sous la forme d'une chaîne et suppose que c'est ASCII, puis étouffe sur les octets qui sont> 127 parce qu'ils ne sont pas ASCII valide. Il est vrai que cette erreur est généralement rencontrée en traitant des données utf-8 (qui utilise aussi le 8ème bit), mais ce n'est pas exclusif. – geoffspear

Répondre

4

votre code d'image de magasin pourrait être comme ça ....

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

faire base64encode des données binaires peuvent augmenter la taille des données lui-même et augmenter le codage cpu et le temps de décodage. Blobstore utilise le même sturcuture de stockage que le magasin de données, de sorte qu'il est simplement plus facile de télécharger des fichiers.

Questions connexes