簡體   English   中英

在ReportLab生成的PDF中包含base64編碼的圖像

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

我正在嘗試解碼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的圖像,但是有什么方法可以避免創建命名的臨時文件,並且只對文件類對象執行此操作,而無需將文件寫入磁盤?

你應該換StringIO的() PIL.Image.open ,所以干脆img_size = ImageReader(PIL.Image.open(img_file)).getSize() 正如Tommaso的回答所暗示的,它實際上是Image.size的一個薄包裝器。 而且,實際上是沒有必要來計算自己的遞減尺寸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)

這段代碼對我來說沒有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)

這個解決方案適合我。 我正在使用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)

我不熟悉ReportLab,但如果你可以直接使用PIL,這將有效:

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

您可以在這里查看PIL Image類引用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM