使用pyfpdf将Base64图像插入pdf

时间:2017-11-09 06:15:48

标签: python fpdf

我在python中使用pyfpdf来生成pdf文件。我有一个Base64,我想插入到pdf文件中,而不必将其保存为我的文件系统中的图像。但是pyfpdf图像函数只接受文件路径。

fpdf.image(name, x = None, y = None, w = 0, h = 0, type = '', link = '')

是否有办法(hack)直接从内存中插入base64或缓冲图像,而无需事先保存到文件系统中?我甚至在github上检查了他们的源代码,但无法想象。

link:https://github.com/reingart/pyfpdf/tree/master/fpdf

2 个答案:

答案 0 :(得分:1)

正如评论中提到的@pvg一样,用你的base64功能覆盖load_resource函数就可以了。

import base64,io

def load_resource(self, reason, filename):
    if reason == "image":
        if filename.startswith("http://") or filename.startswith("https://"):
            f = BytesIO(urlopen(filename).read())
        elif filename.startswith("data"):
            f = filename.split('base64,')[1]
            f = base64.b64decode(f)
            f = io.BytesIO(f)
        else:
            f = open(filename, "rb")
        return f
    else:
        self.error("Unknown resource loading reason \"%s\"" % reason)

编辑:

这是将图像插入pdf的示例代码。我在代码中评论了一些说明。

from fpdf import FPDF
import os
import io
import base64


class PDF(FPDF):

    def load_resource(self, reason, filename):
        if reason == "image":
            if filename.startswith("http://") or filename.startswith("https://"):
                f = BytesIO(urlopen(filename).read())
            elif filename.startswith("data"):
                f = filename.split('base64,')[1]
                f = base64.b64decode(f)
                f = io.BytesIO(f)
            else:
                f = open(filename, "rb")
            return f
        else:
            self.error("Unknown resource loading reason \"%s\"" % reason)


    def sample_pdf(self,img,path):

        self.image(img,h=70,w=150,x=30,y=100,type="jpg")
        #make sure you use appropriate image format here jpg/png
        pdf.output(path, 'F')

if __name__ == '__main__':
    img = # pass your base64 image
    # you can find sample base64 here : https://pastebin.com/CaZJ7n6s

    pdf = PDF()
    pdf.add_page()
    pdf_path = # give path to where you want to save pdf
    pdf.sample_pdf(img,pdf_path) 

答案 1 :(得分:0)

我最近一直在面对这个问题,而Uchiha Madara的回答在我的案例中不起作用,因此我以略有不同的方式解决了它。当我用Uchiha的方法尝试它时,如果您提供的图像没有对代码进行任何修改(没有load_resource函数),我也会遇到同样的FileNotFound错误。由于我确实需要解决方案,而且没有解决方法,因此我研究了可以在

中找到的模块代码。

C:/用户/用户/ AppData /本地/程序/Python/Python38/Lib/site-packages/fpdf/fpdf.py

如果您四处看看,您会注意到图像是通过_parsepng函数导入的。因此,我们需要对其进行编辑以接受base64数据字符串。

基本上,您需要做些什么来修正它:

在该函数中,需要在顶部添加一个elif,以检查“文件名”是否包含指示其为base64的字符串,并且需要导入2个新模块。

将此代码复制并粘贴到第一个if语句下方以检查URL:

elif "data:image/png;base64" in name:
                f = name.split('base64,')[1]
                f = base64.b64decode(f)
                f = io.BytesIO(f)

这只是寻找每个base64编码图像所特有的字符串,如果存在并解码。

您需要在脚本顶部导入base64和io模块,因此只需通过

import base64, io

现在只需像通常一样提供base64字符串作为文件路径,它就可以正常工作(在我使用python 3.8进行的测试中完成)。

如果您有任何疑问,请与我联系,希望以后我能帮助一些人阅读。