2010-09-26 17 views
5

Estoy usando Reportlab para generar un PDF. No se puede recuperar una foto de un modelo.Appengine - Reportlab (Obtener foto del modelo)

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

cuando creo el genero PDF, tengo este error:

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 comento la línea que n.º 419, que llama a la foto, todo va bien. Ya he inspeccionado en Datastore Viewer y los modelos están bien.

¿Alguien puede señalar lo que está mal?

¿Debo usar% s en lugar de str? Pero arroja el mismo error.

Respuesta

12

De acuerdo con ReportLab API reference, drawImage() tiene argumentos 'image, x, y', mientras que parece que está pasando 'x, y, string'.

El argumento de la imagen para drawImage() requiere un nombre de archivo o ImageReader.

De acuerdo con this post, el constructor ImageReader puede tomar varios tipos de argumentos.

Actualización:

En este código que usted envió está asignando el ImageReader a 'imagen', pero que pasa 'imagem' (que no existe) a drawImage:

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

Además, ¿qué tipo de propiedad de modelo es user.photo?

Actualización 2:

Usted está recibiendo un error sobre NoneType - ¿estás seguro user.photo es una mancha válida, y no Ninguno?

Además, un blob is a subclass of str, pero ImageReader requiere un StringIO - por lo que creo que necesita para envolver el blob en un StringIO pasarlo a ImageReader, por ejemplo:

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

Por cierto, yo creo que es que ImageReader('http://www.reportlab.com/rsrc/encryption.gif') puede haber fallado porque puede estar intentando cargar la imagen de ese servidor, utilizando una API que el motor de la aplicación no admite (es decir, no urlfetch).

Actualización 3:

En realidad, parece que es un error en ReportLab.

He descargado version 2.4 of ReportLab, y encontramos este en 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): 

El constructor llama ImageReader _isPILImage para ver si se aprobó una imagen de PIL. Sin embargo, PIL no está disponible en el motor de la aplicación, por lo que Image is None, y por lo tanto hace referencia a Image.Image arroja el in _isPILImage AttributeError: 'NoneType' object has no attribute 'Image'. que está viendo.

También encontré this blog post que describe cómo utilizar ReportLab con imágenes. Consulte la sección "Imágenes en PDF" para obtener detalles sobre cómo solucionar este problema, así como otra modificación necesaria para que funcione en el motor de la aplicación. Tenga en cuenta que no parecen los números de línea en que la entrada en el blog para que coincida con la versión 2.4, que he descargado, o los números de línea en sus mensajes de error - por lo que buscar el código mencionado, en lugar de los números de línea.

También tenga en cuenta que ReportLab sin PIL (es decir, a medida que se ejecutará en el motor de aplicación) sólo puede dibujar imágenes JPEG (como también se menciona en esa entrada en el blog).

Por último, en este código que envió:

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) 

La primera cuestión es que está llamando drawImage() con 'x, y, imagen', cuando los argments deben ser 'imagen, x, y '.

En segundo lugar, ninguno de usuario o p se definen aquí (tal vez se corta ese código?).

En tercer lugar, ¿por qué hay un argumento para obtener la imagen() - Cómo se PARSE algo fuera de la URL cuando se crea la webapp.WSGIApplication()? De lo contrario, la imagen será Ninguna, por lo que no sucederá nada.

Actualización 4:

El error Imaging Library not available, unable to import bitmaps only jpegs que está recibiendo ahora es porque ReportLab es incapaz de leer el jpeg para encontrar su anchura y altura. Quizás el jpeg estaba dañado cuando lo cargó en el blob, o tal vez el jpeg está en un formato que ReportLab no es compatible.

En lib \ utils.py de ReportLab, que temporalmente podría intentar cambiar el siguiente (alrededor de la línea 578 de la versión 2.5):

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

Para esto:

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

Esto le permitirá para ver la excepción real que está lanzando readJPEGInfo(), que podría ayudar a encontrar la causa del problema.

Otra cosa para tratar de ayudar a reducir el problema podría ser la de poner el archivo.jpg cual descargamos para el usuario en su proyecto, a continuación, hacer algo como esto:

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

Esto cargará el jpeg directamente desde el archivo, usando el ImageReader, en lugar de desde el blob.

Si esto funciona, entonces el problema es que su burbuja no es válido, por lo que debe buscar en su código de carga de imágenes. Si falla, el propio jpeg no es válido (o no es compatible con ReportLab).

Update 5:

que está utilizando este:

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

De acuerdo con la documentation on resize en esta página, se necesita un argumento output_encoding que por defecto es PNG.Así que intente esto en su lugar:

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

Gracias Saxon, por su respuesta. Echaré un vistazo al enlace que me enviaste. Puede ser interesante y lo que necesito. Te diré entonces, si funcionó o no – Martinho

+0

Se arroja un error: Archivo "C: \ Users \ hp \ workspace \ myApp \ src \ principal.py", línea 432, en la publicación imagem = ImageReader ('http : //www.reportlab.com/rsrc/encryption.gif ') Archivo "reportlab.zip \ reportlab \ lib \ utils.py", línea 548, en __init__ Archivo "reportlab.zip \ reportlab \ lib \ utils. py ", línea 529, en _isPILImage AttributeError: el objeto 'NoneType' no tiene atributo 'Image' – Martinho

+0

Se lanza un error: Archivo" C: \ Users \ hp \ workspace \ myApp \ src \ principal.py ", línea 432, en la publicación image = ImageReader (user.photo) Archivo "reportlab.zip \ reportlab \ lib \ utils.py", línea 548, en __init__ Archivo "reportlab.zip \ reportlab \ lib \ utils.py", línea 529 , en _isPILImage AttributeError: 'NoneType 'objeto no tiene atributo' Imagen '. Intenté de esta manera image = ImageReader (user.photo) p.drawImage (imagem). También intenté en lugar de obtener el modelo (user.photo), im = ImageReader ('http://www.reportlab.com/rsrc/encryption.gif') c.drawImage (im), tal como se explica en su enlace – Martinho

Cuestiones relacionadas