5

我正在使用 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 吗?但抛出同样的错误。

4

1 回答 1

12

根据ReportLab API 参考,drawImage() 有参数“image, x, y”,而看起来好像您正在传递“x, y, string”。

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

根据这篇文章,ImageReader 构造函数可以采用多种类型的参数。

更新:

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

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

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

更新 2:

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

此外,blob 是 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 中的一个错误。

我下载了 ReportLab 的 2.4 版,并在 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'.您所看到的。

我还发现这篇博客文章描述了如何将 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)

第一个问题是当参数应该是 'image, x, y' 时,您正在使用 'x, y, image' 调用 drawImage()。

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

第三,为什么 get() 有一个 image 参数——当你创建 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)

根据此页面上有关调整大小的文档,它采用默认为 PNG 的 output_encoding 参数。所以试试这个:

photo = images.resize(self.request.get('photo'), 32, 32, images.JPEG)
于 2010-09-28T07:56:20.057 回答