2010-09-26 14 views
5

J'utilise Reportlab pour générer un fichier PDF. Impossible de récupérer une photo d'un modèle.Appengine - Reportlab (Obtenir une photo du modèle)

#Personal Info    
    p.drawImage('myPhoto.jpg', 40, 730) 
    p.drawString(50, 670, 'Your name:' + '%s' % user.name) 
    p.drawImage (50, 640, 'Photo: %s' % (user.photo)) 

Lorsque je crée sur Generate PDF, j'ai obtenu cette erreur:

Traceback (most recent call last): 
    File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\webapp\__init__.py", line 513, in __call__ 
    handler.post(*groups) 
    File "C:\Users\hp\workspace\myApp\src\main.py", line 419, in post 
    p.drawImage (50, 640, 'Photo: %s' %     (user.photo)) 
    File "reportlab.zip\reportlab\pdfgen\canvas.py", line 825, in drawImage 
    File "reportlab.zip\reportlab\pdfbase\pdfdoc.py", line 2076, in __init__ 
    File "C:\Python25\lib\ntpath.py", line 189, in splitext 
    i = p.rfind('.') 
AttributeError: 'int' object has no attribute 'rfind' 

Si je commente la ligne qui n.º 419, qui appelle la photo, tout va bien. J'ai déjà inspecté dans Datastore Viewer et les modèles sont ok.

Quelqu'un peut-il signaler ce qui ne va pas?

Devrais-je utiliser% s au lieu de str? Mais lance la même erreur.

Répondre

12

Selon le ReportLab API reference, drawImage() a les arguments 'image, x, y', alors qu'il semble que vous passez 'x, y, string'.

L'argument image de drawImage() nécessite un nom de fichier ou ImageReader. Selon le , le constructeur ImageReader peut prendre plusieurs types d'arguments.

Mise à jour:

Dans ce code que vous vous assignez au courant de la ImageReader à 'l'image', mais en passant 'Imagem' (qui n'existe pas) à drawImage:

image = ImageReader(user.photo) 
p.drawImage(imagem) 

En outre, quel type de propriété de modèle est user.photo?

Mise à jour 2:

Vous obtenez une erreur au sujet NoneType - êtes-vous sûr user.photo est un blob valide, et non pas?

En outre, un blob is a subclass of str, mais ImageReader nécessite une StringIO - donc je pense que vous avez besoin d'envelopper le blob dans un StringIO pour passer à ImageReader, par exemple:

import StringIO 
image = ImageReader(StringIO.StringIO(user.photo)) 
p.drawImage(image) 

Soit dit en passant, je suppose ImageReader('http://www.reportlab.com/rsrc/encryption.gif') peut avoir échoué car il peut être en train de tenter de charger l'image à partir de ce serveur, en utilisant une API que le moteur de l'application ne prend pas en charge (par exemple, urlfetch).

Mise à jour 3:

En fait, il semble que ce soit un bug dans ReportLab.

J'ai téléchargé version 2.4 of ReportLab, et trouvé cela dans utils.py:

def _isPILImage(im): 
    try: 
     return isinstance(im,Image.Image) 
    except ImportError: 
     return 0 

class ImageReader(object): 
    "Wraps up either PIL or Java to get data from bitmaps" 
    _cache={} 
    def __init__(self, fileName): 
     ... 
     if _isPILImage(fileName): 

Le constructeur appelle de ImageReader _isPILImage pour voir si elle a été adoptée une image PIL. Cependant PIL n'est pas disponible sur le moteur de l'application, donc l'image est Aucune, et donc référencer Image.Image jette le in _isPILImage AttributeError: 'NoneType' object has no attribute 'Image'. que vous voyez.J'ai également trouvé this blog post qui décrit comment utiliser ReportLab avec des images. Consultez la section "Images au format PDF" pour plus de détails sur la façon de résoudre ce problème, ainsi qu'une autre modification nécessaire pour le faire fonctionner sur le moteur de l'application. Notez que les numéros de ligne dans ce billet de blog ne semblent pas correspondre à la version 2.4 que j'ai téléchargée, ou aux numéros de ligne dans vos messages d'erreur - alors recherchez le code mentionné, plutôt que les numéros de ligne.

Notez également que ReportLab sans PIL (c'est-à-dire qu'il s'exécutera sur le moteur de l'application) peut uniquement dessiner des images JPEG (comme mentionné également dans ce billet de blog).

Enfin, dans ce code affiché:

def get(self, image): 
    if image is not None: 
     image = ImageReader(StringIO.StringIO(user.photo)) 
     p.drawImage(40, 700, image) 
     p.setLineWidth(.3) 
     p.setFont('Helvetica', 10) 
     p.line(50, 660, 560, 660) 

Le premier problème est que vous appelez drawImage() avec x, y, image », lorsque les argments doivent être « l'image, x, y '. Deuxièmement, ni utilisateur ni p sont définis ici (peut-être vous découper ce code?). Troisièmement, pourquoi y a-t-il un argument image à obtenir() - est-ce que vous pars quelque chose hors de l'URL lorsque vous créez le fichier webapp.WSGIApplication()? Si non, alors l'image sera Aucune, ce qui explique pourquoi rien ne se passera.

Mise à jour 4:

L'erreur Imaging Library not available, unable to import bitmaps only jpegs que vous obtenez est maintenant parce que ReportLab ne peut pas lire le jpeg pour trouver sa largeur et sa hauteur. Peut-être que le jpeg a été corrompu quand vous l'avez chargé dans le blob, ou peut-être que le jpeg est dans un format que ReportLab ne supporte pas.

Dans lib \ le utils.py de ReportLab, vous pouvez temporairement essayer de modifier les éléments suivants (autour de la ligne 578 de la version 2.5):

try: 
    self._width,self._height,c=readJPEGInfo(self.fp) 
except: 
    raise RuntimeError('Imaging Library not available, unable to import bitmaps only jpegs') 

Pour ceci:

self._width,self._height,c=readJPEGInfo(self.fp) 

Cela vous permettra pour voir l'exception réelle que readJPEGInfo() lance, ce qui pourrait aider à trouver la cause du problème.

Une autre chose à essayer d'aider à réduire le problème pourrait être de mettre le file.jpg que vous avez téléchargé pour l'utilisateur dans votre projet, faire quelque chose comme ceci:

imagem = canvas.ImageReader(StringIO.StringIO(open('file.jpg', 'rb').read())) 

Cela va charger le jpeg directement à partir du fichier, en utilisant ImageReader, au lieu de blob. Si cela fonctionne, le problème est que votre blob n'est pas valide, vous devriez donc regarder votre code de téléchargement d'image. Si cela échoue, alors le jpeg lui-même n'est pas valide (ou n'est pas supporté par ReportLab).

Mise à jour 5:

Vous utilisez ceci:

photo = images.resize(self.request.get('photo'), 32, 32) 

Selon le documentation on resize sur cette page, il faut un argument output_encoding qui par défaut PNG.Donc, essayez ceci à la place:

photo = images.resize(self.request.get('photo'), 32, 32, images.JPEG) 
+0

Merci Saxon, pour votre réponse. Je vais regarder le lien que vous m'avez envoyé. Ça pourrait être intéressant et ce dont j'ai besoin. Je vais vous dire alors, si cela a fonctionné ou non – Martinho

+0

Il se produit une erreur: Fichier "C: \ Utilisateurs \ hp \ espace de travail \ monApp \ src \ principal.py", ligne 432, dans la publication imagem = ImageReader ('http : //www.reportlab.com/rsrc/encryption.gif ') Fichier "reportlab.zip \ reportlab \ lib \ utils.py", ligne 548, dans __init__ Fichier "reportlab.zip \ reportlab \ lib \ utils. py ", ligne 529, dans _isPILImage AttributeError: L'objet 'NoneType' n'a pas d'attribut 'Image' – Martinho

+0

Il génère une erreur: Fichier" C: \ Users \ hp \ workspace \ monApp \ src \ principal.py ", ligne 432, dans la publication image = ImageReader (user.photo) Fichier "reportlab.zip \ reportlab \ lib \ utils.py", ligne 548, dans __init__ Fichier "reportlab.zip \ reportlab \ lib \ utils.py", ligne 529 , dans _isPILImage AttributeError: 'NoneType 'objet n'a pas d'attribut' Image '. J'ai essayé de cette façon image = ImageReader (user.photo) p.drawImage (imagem). J'ai également essayé au lieu d'obtenir le modèle (user.photo), im = ImageReader ('http://www.reportlab.com/rsrc/encryption.gif') c.drawImage (im), tout comme expliqué dans votre lien – Martinho

Questions connexes