Python 使用pyfpdf将Base64图像插入pdf
我在python中使用pyfpdf生成pdf文件。我有一个Base64,我想将它插入到pdf文件中,而不必将其保存为文件系统中的图像。但是pyfpdf image函数只接受文件路径Python 使用pyfpdf将Base64图像插入pdf,python,fpdf,Python,Fpdf,我在python中使用pyfpdf生成pdf文件。我有一个Base64,我想将它插入到pdf文件中,而不必将其保存为文件系统中的图像。但是pyfpdf image函数只接受文件路径 fpdf.image(name, x = None, y = None, w = 0, h = 0, type = '', link = '') 有没有一种方法(hack)可以直接从内存中插入base64或缓冲图像,而不必事先保存到文件系统中?我甚至在github上查看了他们的源代码,但还是不明白 链接:正如注释中
fpdf.image(name, x = None, y = None, w = 0, h = 0, type = '', link = '')
有没有一种方法(hack)可以直接从内存中插入base64或缓冲图像,而不必事先保存到文件系统中?我甚至在github上查看了他们的源代码,但还是不明白
链接:正如注释中提到的@pvg一样,使用base64功能覆盖load\u资源功能可以实现这一点
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)
我最近一直在面对这个问题,而来自Uchiha Madara的答案在我的案例中不起作用,所以我用一种稍微不同的方式解决了这个问题。当我尝试使用Uchiha的方法时,我发现了与您在未对代码进行任何修改的情况下(未使用load_resource函数)提供图像时相同的FileNotFound错误。因为我真的需要一个解决方案,而且没有办法,所以我研究了可以在中找到的模块代码 C:/Users/user/AppData/Local/Programs/Python38/Lib/site-packages/fpdf/fpdf.py 如果您环顾四周,会发现图像是通过_parsepng函数导入的。因此,我们需要编辑它以接受base64数据字符串 基本上,您需要做什么来修复它: 在函数中,您需要在顶部添加一个elif,以检查“filename”是否包含指示其为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进行的测试中)
如果您有任何问题,请与我联系,我希望我能在将来帮助一些人阅读本文 您可以子类化
fpdf
并覆盖load\u resource
以返回BytesIO
类似文件的对象。这是一个好主意。如果我被卡住了,你可以发布你的详细答案,这会对我有帮助。所有图像解析代码调用load\u resource
,如果有不清楚的地方,去看看并问一个特定的问题。或者,您可能希望使用不同的pdf库进行探索,因为这一个看起来像是一个不洁的混乱(它是一个PHP端口)。我也觉得这个库出了问题,但它非常简单。您认为这在纯python环境中有效吗?还是我需要安装任何php依赖项?我想知道为什么“PHP端口”在这里是个问题。我正处于项目的早期阶段,所以您对它的看法将非常有帮助。我不知道,从我所看到的一点来看,它看起来像纯python。我所说的“PHP端口”是指有人将一些PHP代码转换成python。它似乎已经有一段时间没有维护了。另一方面,如果它起作用并且做了你想做的事情,你就会得到更多的力量。如果您还没有使用文件系统中的图像来测试它,那么您可能需要使用文件系统中的图像来测试它。在if filename.startswith(“http://”)或filename.startswith(“https://”)块中,您需要将f=BytesIO(…)
更改为f=io.BytesIO(…)
。我也不确定urlopen(…)
属于哪个库。我的IDE显示它也无法确定这一点。这方面的修改会很好。非常感谢。对于发现此问题的任何其他人。此方法仅适用于开发版本fpdf。在编写本文时,pypi(1.7.2)上的版本以不同的方式处理加载图像。要使这个答案与pypi上的版本一起工作,您需要使用Github上主分支的代码重写FPDF.\u parsepng/jpg。