我在python中使用pyfpdf来生成pdf文件。我有一个Base64,我想插入到pdf文件中,而不必将其保存为我的文件系统中的图像。但是pyfpdf图像函数只接受文件路径。
fpdf.image(name, x = None, y = None, w = 0, h = 0, type = '', link = '')
是否有办法(hack)直接从内存中插入base64或缓冲图像,而无需事先保存到文件系统中?我甚至在github上检查了他们的源代码,但无法想象。
答案 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进行的测试中完成)。
如果您有任何疑问,请与我联系,希望以后我能帮助一些人阅读。