我正在使用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吗?但抛出相同的错误。
答案 0 :(得分:12)
根据ReportLab API reference,drawImage()的参数是'image,x,y',而它看起来好像在传递'x,y,string'。
drawImage()的image参数需要文件名或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(即它将在app引擎上运行)只能绘制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()。
其次,这里没有定义用户或p(也许你删除了那些代码?)。
第三,为什么get()有一个图像参数 - 你在创建webapp.WSGIApplication()时是否解析了一些URL?如果没有,则图像将为None,这就是为什么不会发生的原因。
更新4:
您现在获得的Imaging Library not available, unable to import bitmaps only jpegs
错误是因为ReportLab无法读取jpeg以查找其宽度和高度。当你将它加载到blob中时,jpeg可能已损坏,或者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,它采用output_encoding参数,默认为PNG。所以试试这个:
photo = images.resize(self.request.get('photo'), 32, 32, images.JPEG)