我正在尝试解码base64编码的图像并将其放入我使用ReportLab生成的PDF中。我目前这样做(image_data
是base64编码的图像,story
已经是ReportLab的故事):
# 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)
但是这给了我 IOError ,并显示以下消息:“无法识别图像文件”。
我知道ReportLab使用PIL来读取不同于jpg的图像,但有没有办法可以避免创建命名的临时文件,只能使用类似文件的对象,而无需将文件写入磁盘?
答案 0 :(得分:2)
你应该按PIL.Image.open
包装StringIO(),所以只需img_size = ImageReader(PIL.Image.open(img_file)).getSize()
。正如Tommaso的回答所暗示的,它实际上是Image.size的一个薄包装器。此外,实际上没有必要在您自己的bound
reportlab模式下计算desc大小。图像可以为您完成:
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)
答案 1 :(得分:0)
我对ReportLab并不熟悉,但如果您可以直接使用PIL,那么这将起作用:
...
img = Image.open(img_file)
width, height = img.size
...
您可以在这里查看PIL Image类references
答案 2 :(得分: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)
答案 3 :(得分:0)
此解决方案对我有用。我正在将Flask与Google App Engine结合使用。
from reportlab.platypus import Image
from reportlab.lib.units import mm
import cStringIO
from base64 import b64decode
story=[]
encoded_image = "...."
decoded_img = b64decode(encoded_image)
img_string = cStringIO.StringIO(decoded_img)
img_string.seek(0)
im = Image(img_string, 180*mm, 100*mm, kind='bound')
story.append(im)
我已从客户端收到图像并保存在数据库中
from base64 import b64decode
image = request.files['image'].read()
encoded_image = b64encode(image)