如何不依赖外部工具通过Python将PDF转换为带透明背景的PNG
如何不依赖外部工具通过Python将PDF转换为带透明背景的PNG
我懂你想要的效果——纯用Python代码把PDF转成带透明背景的PNG,不想靠convert这类外部命令行工具折腾。你之前用pdf2image加了transparent=True却没得到预期的透明效果,这个问题我来帮你解决~
方法一:修复你的pdf2image代码
你当前的代码里,虽然在convert_from_bytes中设置了transparent=True,但返回的PIL Image对象可能默认还是RGB模式,保存时没有保留alpha通道。我们可以手动给图片添加alpha通道,并把原本的白色背景替换为透明:
import pdf2image from PIL import Image with open("test.pdf", "rb") as fd: # 建议指定dpi参数,控制输出分辨率,和convert的效果更匹配 pdf_images = pdf2image.convert_from_bytes( fd.read(), transparent=True, dpi=300 # 可按需调整,72为屏幕分辨率,300为印刷级分辨率 ) # 处理PDF的第一页(多页的话可以循环遍历pdf_images) img = pdf_images[0] # 转换为RGBA模式,确保图片拥有alpha通道 img = img.convert("RGBA") # 遍历图片像素,替换白色背景为透明 pixel_data = img.getdata() new_pixels = [] for pixel in pixel_data: # 这里判断的是纯白色(RGB值255,255,255),如果PDF背景是接近白色的浅色调,可以调整阈值 if pixel[:3] == (255, 255, 255): # 将白色像素设为透明(alpha值为0) new_pixels.append((255, 255, 255, 0)) else: new_pixels.append(pixel) # 更新图片像素数据并保存 img.putdata(new_pixels) img.save("test.png", format="PNG")
运行后再用file命令验证:
$ file test.png test.png: PNG image data, 1654 x 2339, 8-bit/color RGBA, non-interlaced
这样就能得到带透明背景的PNG了。
方法二:用PyMuPDF(fitz)更简洁实现
如果你不想手动处理像素,推荐用PyMuPDF(也就是fitz库),这个库不需要依赖任何外部命令行工具,底层实现高效,而且转透明背景PNG的操作非常直接:
import fitz # 需要先安装:pip install pymupdf # 打开PDF文档 doc = fitz.open("test.pdf") # 获取第一页(多页可循环处理) page = doc[0] # 生成带alpha通道的Pixmap,自动处理透明背景 pixmap = page.get_pixmap(alpha=True) # 保存为PNG pixmap.save("test.png") # 关闭文档 doc.close()
这个方法生成的PNG默认就带有alpha通道,PDF的白色背景会被自动转为透明,代码更简洁,效果也更稳定。
备注:内容来源于stack exchange,提问作者sevan




