2012-04-02 77 views
2

我想解码base64编码的图像,并将其放入使用ReportLab生成的PDF中。目前,我那样做(image_data是base64编码图像,story已经是ReportLab的故事):在ReportLab生成的PDF中包含base64编码的图像

# There is some "story" I append every element 
img_height = 1.5 * inch # max image height 
img_file = tempfile.NamedTemporaryFile(mode='wb', suffix='.png') 
img_file.seek(0) 
img_file.write(image_data.decode('base64')) 
img_file.seek(0) 
img_size = ImageReader(img_file.name).getSize() 
img_ratio = img_size[0]/float(img_size[1]) 
img = Image(img_file.name, 
    width=img_ratio * img_height, 
    height=img_height, 
) 
story.append(img) 

和它的作品(虽然看起来仍然难看给我)。我想过摆脱临时文件(不应该像文件一样的对象做诡计?)。

为了摆脱的临时文件我试图用StringIO模块,创建类似文件的对象,并通过它,而不是文件名:

# There is some "story" I append every element 
img_height = 1.5 * inch # max image height 
img_file = StringIO.StringIO() 
img_file.seek(0) 
img_file.write(image_data.decode('base64')) 
img_file.seek(0) 
img_size = ImageReader(img_file).getSize() 
img_ratio = img_size[0]/float(img_size[1]) 
img = Image(img_file, 
    width=img_ratio * img_height, 
    height=img_height, 
) 
story.append(img) 

但是这给了我IO错误以下消息:“无法识别图像文件”。

我知道ReportLab使用PIL来读取不同于JPG的图像,但是有什么办法可以避免创建指定的临时文件,并且只对文件类对象执行此操作,而无需将文件写入磁盘?

回答

0

我不熟悉的ReportLab的,但如果你可以使用PIL直接这将工作:

... 
img = Image.open(img_file) 
width, height = img.size 
... 

,你可以看看这里PIL Image类references

2

你应该换StringIO的()由PIL.Image.open,所以只需img_size = ImageReader(PIL.Image.open(img_file)).getSize()。正如Tommaso的回答所暗示的,它实际上是Image.size的一个简单封装。而且,实际上是没有必要来计算自己的递减大小,reportlab.Image的bound模式可以为你做到这一点:

img_height = 1.5 * inch # max image height 
img_file = StringIO.StringIO(image_data.decode('base64')) 
img_file.seek(0) 
img = Image(PIL.Image.open(img_file), 
      width=float('inf'), 
      height=img_height, 
      kind='bound') 
) 
story.append(img) 
0

此代码为我工作没有PIL,作为图像已经是JPEG: raw只是将base64字符串拉出字典。我只是将解码的“字符串”包装在一个StringIO中。

 raw = element['photographs'][0]['jpeg'] 
     photo = base64.b64decode(raw) 
     c.drawImage(ImageReader(StringIO.StringIO(photo)), 0.5*inch, self.y, height = self.PHOTOHEIGHT, preserveAspectRatio = True)