简体   繁体   English

在ReportLab生成的PDF中包含base64编码的图像

[英]Including base64-encoded image in ReportLab-generated PDF

I am trying to decode base64-encoded image and put it into PDF I generate using ReportLab. 我正在尝试解码base64编码的图像并将其放入我使用ReportLab生成的PDF中。 I currently do it like that ( image_data is base64-encoded image, story is already a ReportLab's story): 我目前这样做( 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)

and it works (although still looks ugly to me). 它工作(虽然看起来仍然丑陋)。 I thought about getting rid of the temporary file (shouldn't file-like object do the trick?). 我想要摆脱临时文件(不应该像文件一样的对象吗?)。

To get rid of the temporary file I tried to use StringIO module, to create file-like object and pass it instead of file name: 为了摆脱我试图使用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)

But this gives me IOError with the following message: " cannot identify image file ". 但这给了我IOError以及以下消息:“ 无法识别图像文件 ”。

I know ReportLab uses PIL to read images different than jpg, but is there any way I can avoid creating named temporary files and do this only with file-like objects, without writing files to the disk? 我知道ReportLab使用PIL来读取不同于jpg的图像,但是有什么方法可以避免创建命名的临时文件,并且只对文件类对象执行此操作,而无需将文件写入磁盘?

You should wrap StringIO() by PIL.Image.open , so simply img_size = ImageReader(PIL.Image.open(img_file)).getSize() . 你应该换StringIO的() PIL.Image.open ,所以干脆img_size = ImageReader(PIL.Image.open(img_file)).getSize() Its actually a thin wrapper around Image.size, as Tommaso's answer suggests. 正如Tommaso的回答所暗示的,它实际上是Image.size的一个薄包装器。 Also, there is actually no need to calculate the desc size on your own, bound mode of reportlab.Image could do it for you: 而且,实际上是没有必要来计算自己的递减尺寸bound reportlab.Image的模式,可以为你做到这一点:

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)

This code is working for me without PIL, as the image is already a JPEG: raw just pulls the base64 string out of a dictionary. 这段代码对我来说没有PIL,因为图像已经是JPEG:raw只是将base64字符串从字典中拉出来。 I just wrap the decoded "string" in a StringIO. 我只是将解码后的“字符串”包装在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)

This solution works for me. 这个解决方案适合我。 I'm using Flask with Google App Engine. 我正在使用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)

I have received the image from the client and saved in the database: 我从客户端收到了图像并保存在数据库中:

from base64 import b64decode
image = request.files['image'].read()
encoded_image = b64encode(image)

I am not familiar with ReportLab but if you can use PIL directly this will work: 我不熟悉ReportLab,但如果你可以直接使用PIL,这将有效:

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

you can have a look here for PIL Image class references 您可以在这里查看PIL Image类引用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 AppEngine 中存储 base64 编码的图像? - How do I store a base64-encoded image in AppEngine? base64编码图像; binascii.Error: 无效的 base64 编码 - base64 encoding image; binascii.Error: Invalid base64-encoded 如何从发布的base64编码图像创建MongoDB / mongoengine ImageField? - How to Create a MongoDB/mongoengine ImageField from POSTed base64-encoded image? Python,获取图像对象的 base64 编码的 MD5 哈希 - Python, get base64-encoded MD5 hash of an image object 在 ReportLab PDF 中包含远程图像 - Including a remote image in ReportLab PDF 如何反序列化base64编码的数据并将其与DRF一起使用 - How to deserialize base64-encoded data and use it with DRF 将base64编码的字符串转换为十六进制int - Convert base64-encoded string into hex int PEM 格式的 base64 编码公钥的序列化 - Serialization of a base64-encoded public key in PEM format Fernet 密钥必须是 32 个 url 安全的 base64 编码字节 - Fernet key must be 32 url-safe base64-encoded bytes 如何在不写入磁盘的情况下将 numpy 数组编码为 base64 编码的 PNG? - How do I encode a numpy array to a base64-encoded PNG without writing to disk?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM