2010-09-26 13 views
5

Ich benutze Reportlab, um eine PDF zu generieren. Kann ein Foto nicht von einem Modell abrufen.Appengine - Reportlab (Get Foto von Model)

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

Wenn ich auf PDF erzeugen create, bekam ich diese Fehlermeldung:

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' 

Wenn ich die Zeile Stellung nehmen, die 419 n.º, dass das Foto aufruft, geht alles in Ordnung. Ich habe bereits in Datastore Viewer überprüft und die Modelle sind in Ordnung.

Kann jemand darauf hinweisen, was schief läuft?

Sollte ich% s anstelle von str verwenden? Aber wirft denselben Fehler.

Antwort

12

Nach der ReportLab API reference, hat drawImage() Argumente 'Bild, x, y', während es aussieht, als ob Sie 'x, y, string' übergeben.

Das Image-Argument für DrawImage() benötigt einen Dateinamen oder ImageReader.

Gemäß this post kann der ImageReader-Konstruktor mehrere Arten von Argumenten annehmen.

Update:

In diesem Code, die Sie auf dem Laufenden Sie die Imagereader zu 'Bild' zuweisen, aber vorbei 'imagem' zu drawImage (was nicht vorhanden ist):

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

Welche Art von Modelleigenschaft ist user.photo?

Update 2:

Sie eine Fehlermeldung über NoneType bekommen - sind Sie sicher, user.photo ein gültiges Blob ist, und nicht None?

Auch ein blob is a subclass of str, aber Imagereader ein StringIO erfordert - so dass ich glaube, Sie brauchen das Blob in einem StringIO wickeln Sie es zu Imagereader zu passieren, zum Beispiel:

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

By the way, meine Vermutung ist, dass ImageReader('http://www.reportlab.com/rsrc/encryption.gif') möglicherweise fehlgeschlagen ist, weil es möglicherweise versucht, das Image von diesem Server mithilfe einer API zu laden, die von der App Engine nicht unterstützt wird (dh nicht urlfetch).

Update 3:

Eigentlich sieht es aus wie es ein Fehler in ReportLab ist.

ich heruntergeladen version 2.4 of ReportLab, und fanden diese in 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): 

Der Imagereader Konstruktor ruft _isPILImage zu sehen, ob es ein PIL Bild übergeben wurde. PIL ist jedoch nicht in der App-Engine verfügbar, daher ist Bild Keines und daher verweist Image.Image auf die in _isPILImage AttributeError: 'NoneType' object has no attribute 'Image'., die Sie sehen.

Ich fand auch this blog post, die beschreibt, wie ReportLab mit Bildern verwendet wird. Im Abschnitt "Bilder in PDFs" finden Sie Details zur Behebung dieses Problems sowie weitere Änderungen, die erforderlich sind, damit es in App Engine funktioniert. Beachten Sie, dass die Zeilennummern in diesem Blogpost nicht mit der heruntergeladenen Version von Version 2.4 oder den Zeilennummern in Ihren Fehlernachrichten übereinstimmen. Suchen Sie daher nach dem angegebenen Code und nicht nach den Zeilennummern.

Beachten Sie auch, dass ReportLab ohne PIL (dh wie es auf App Engine ausgeführt wird) nur JPEG-Bilder zeichnen kann (wie auch in diesem Blog-Post erwähnt).

schließlich in diesem Code, den Sie geschrieben:

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) 

Das erste Problem ist, dass Sie drawImage() mit 'x, y, Bild' anrufen, wenn die argments sein sollten ‚Bild, x, y ".

Zweitens, weder Benutzer oder p sind hier definiert (vielleicht schneiden Sie diesen Code?).

Drittens, warum gibt es ein Bild Argument zu bekommen() - parsen Sie etwas aus der URL beim Erstellen der webapp.WSGIApplication()? Wenn nicht, dann wird das Bild None sein, weshalb nichts passieren wird.

Update 4:

Die Imaging Library not available, unable to import bitmaps only jpegs Fehler, die Sie jetzt bekommen ist, weil ReportLab nicht in der Lage ist, die JPEG zu lesen seine Breite und Höhe zu finden. Vielleicht war das JPEG beschädigt, als Sie es in den Blob geladen haben, oder vielleicht ist das JPEG in einem Format, das ReportLab nicht unterstützt.

In ReportLab lib \ utils.py, könnten Sie vorübergehend versuchen Ändern der folgenden (um die Linie 578 von 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') 

Um genau dies:

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

dies ermöglicht es Ihnen um die tatsächliche Ausnahme zu sehen, die readJPEGInfo() wirft, was helfen könnte, die Ursache des Problems zu finden.

Eine andere Sache, zu versuchen, die file.jpg, um das Problem einzugrenzen zu helfen könnte sein, zu setzen, die Sie für den Benutzer in das Projekt hochgeladen, dann tun Sie etwas wie folgt aus:

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

Diese die JPEG-laden werden direkt aus der Datei mit dem ImageReader statt aus dem Blob.

Wenn dies funktioniert, ist das Problem, dass Ihr Blob ungültig ist, also sollten Sie sich Ihren Bildupload-Code ansehen. Wenn dies fehlschlägt, ist das JPEG selbst ungültig (oder wird von ReportLab nicht unterstützt).

Update 5:

Sie dies mit:

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

Nach dem documentation on resize auf dieser Seite, dauert es eine output_encoding Argument zu PNG welche standardmäßig.So versuchen Sie dieses stattdessen:

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

Dank Saxon, für Ihre Antwort. Ich sehe mir den Link an, den du mir geschickt hast. Es könnte interessant sein und was ich brauche. Ich werde Ihnen dann sagen, ob es funktioniert oder nicht – Martinho

+0

Es wirft einen Fehler: Datei "C: \ Benutzer \ hp \ workspace \ myApp \ src \ principal.py", Zeile 432, in der Post imagem = ImageReader ('http : //www.reportlab.com/rsrc/encryption.gif ') Datei "reportlab.zip \ reportlab \ lib \ utils.py", Zeile 548, in __init__ Datei "reportlab.zip \ reportlab \ lib \ utils. py ", Zeile 529, in _isPILImage AttributError: Objekt 'NoneType' hat kein Attribut 'Image' – Martinho

+0

Es wird ein Fehler ausgegeben: Datei" C: \ Benutzer \ hp \ workspace \ myApp \ src \ principal.py ", Zeile 432, in Beitrag image = ImageReader (user.photo) Datei "reportlab.zip \ reportlab \ lib \ utils.py", Zeile 548, in __init__ Datei "reportlab.zip \ reportlab \ lib \ utils.py", Zeile 529 , in _isPILImage AttributeError: 'KeinTyp 'Objekt hat kein Attribut' Bild '. Ich habe es so probiert image = ImageReader (user.photo) p.drawImage (image). Ich habe auch versucht, anstatt das Modell zu bekommen (user.photo), im = ImageReader ('http://www.reportlab.com/rsrc/encryption.gif') c.drawImage (im), genau wie in erklärt Ihr Link – Martinho