【问题标题】:Appengine - Reportlab (Get Photo from Model)Appengine - Reportlab(从模型中获取照片)
【发布时间】:2010-09-26 17:08:40
【问题描述】:

我正在使用 Reportlab 生成 PDF。 无法从模型中检索照片。

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

当我在生成 PDF 时创建时,出现此错误:

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'

如果我评论 n.º 419 的行,即调用照片,一切都很好。 我已经在 Datastore Viewer 中检查过,模型没问题。

谁能指出哪里出了问题?

我应该使用 %s 代替 str 吗?但抛出同样的错误。

【问题讨论】:

    标签: python google-app-engine django-models reportlab


    【解决方案1】:

    根据ReportLab API reference,drawImage() 有参数'image, x, y',而它看起来好像你在传递'x, y, string'。

    drawImage() 的图像参数需要一个文件名或 ImageReader。

    根据this post,ImageReader 构造函数可以采用多种类型的参数。

    更新:

    在您发布的这段代码中,您将 ImageReader 分配给“image”,但将“imagem”(不存在)传递给 drawImage:

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

    另外,user.photo 是什么类型的模型属性?

    更新 2:

    您收到有关 NoneType 的错误 - 您确定 user.photo 是有效的 blob,而不是 None?

    另外,blob is a subclass of str,但 ImageReader 需要 StringIO - 所以我认为您需要将 blob 包装在 StringIO 中以将其传递给 ImageReader,例如:

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

    顺便说一句,我的猜测是 ImageReader('http://www.reportlab.com/rsrc/encryption.gif') 可能失败了,因为它可能正在尝试使用应用引擎不支持的 API(即,不是 urlfetch)从该服务器加载图像。

    更新 3:

    实际上它看起来像是 ReportLab 中的一个错误。

    我下载了version 2.4 of ReportLab,在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):
    

    ImageReader 构造函数调用 _isPILImage 以查看是否传递了 PIL 图像。但是 PIL 在应用引擎上不可用,因此 Image 是 None,因此引用 Image.Image 会抛出您所看到的 in _isPILImage AttributeError: 'NoneType' object has no attribute 'Image'.

    我还找到了this blog post,它描述了如何将 ReportLab 与图像一起使用。有关如何解决此问题的详细信息,以及使其在应用程序引擎上运行所需的另一项修改,请参阅“PDF 中的图像”部分。请注意,该博文中的行号似乎与我下载的 2.4 版本或您的错误消息中的行号不匹配 - 所以请搜索提到的代码,而不是行号。

    另请注意,没有 PIL 的 ReportLab(即它将在​​应用引擎上运行)只能绘制 JPEG 图像(如该博客文章中所述)。

    最后,在您发布的这段代码中:

    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)
    

    第一个问题是你用'x, y, image'调用drawImage(),而参数应该是'image, x, y'。

    其次,这里既没有定义 user 也没有定义 p(也许你删掉了那个代码?)。

    第三,为什么 get() 有一个图像参数 - 当你创建 webapp.WSGIApplication() 时,你会从 URL 中解析出一些东西吗?如果不是,那么 image 将为 None,这就是为什么什么都不会发生的原因。

    更新 4:

    您现在得到的Imaging Library not available, unable to import bitmaps only jpegs 错误是因为 ReportLab 无法读取 jpeg 以找到其宽度和高度。可能 jpeg 在您将其加载到 blob 时已损坏,或者 jpeg 的格式可能是 ReportLab 不支持的。

    在 ReportLab 的 lib\utils.py 中,您可以暂时尝试更改以下内容(大约 2.5 版的第 578 行):

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

    仅此:

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

    这将允许您查看readJPEGInfo() 抛出的实际异常,这可能有助于找到问题的原因。

    尝试帮助缩小问题范围的另一件事可能是将您为用户上传的 file.jpg 放入您的项目中,然后执行以下操作:

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

    这将使用 ImageReader 直接从文件加载 jpeg,而不是从 blob。

    如果可行,那么问题在于您的 blob 无效,因此您应该查看您的图片上传代码。如果失败,则 jpeg 本身无效(或 ReportLab 不支持)。

    更新 5:

    你正在使用这个:

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

    根据此页面上的documentation on resize,它采用默认为 PNG 的 output_encoding 参数。所以试试这个:

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

    【讨论】:

    • 感谢撒克逊人的回复。我会看看你发给我的链接。这可能很有趣,也是我需要的。那我会告诉你,如果它有效与否
    • 它抛出一个错误:文件 "C:\Users\hp\workspace\myApp\src\principal.py",第 432 行,在 post imagem = ImageReader('reportlab.com/rsrc/encryption.gif') File "reportlab .zip\reportlab\lib\utils.py",第 548 行,在 init 文件 "reportlab.zip\reportlab\lib\utils.py",第 529 行,在 _isPILImage AttributeError: 'NoneType' 对象中没有属性“图像”
    • 它会抛出一个错误:文件“C:\Users\hp\workspace\myApp\src\principal.py”,第 432 行,在 post image = ImageReader(user.photo) 文件“reportlab. zip\reportlab\lib\utils.py",第 548 行,在 init 文件 "reportlab.zip\reportlab\lib\utils.py",第 529 行,在 _isPILImage AttributeError: 'NoneType' 对象有没有属性“图像”。我试过这种方式 image = ImageReader(user.photo) p.drawImage (imagem) 。我也试过而不是获取模型(user.photo),im=ImageReader('reportlab.com/rsrc/encryption.gif')c.drawImage(im),就像你的链接中解释的那样
    • 我知道,这个错误发生了,因为我把葡萄牙语翻译成了英语。这就是原因,但在代码中会出错。
    • 类用户:photo = db.BlobProperty()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多