esXGray功能解析01:全自动漂白PDF,使用PyMuPDF替换PDF中所有图片
esXGray可以用来直接漂白一份PDF中的所有图片,之前漂白PDF全文图片的功能有些问题,今日换了一种实现方式,核心思路如下:
- 遍历所有图片记录bbox信息
- 删除所有图片
- 将图片按顺序添加到PDF中实现替换功能
前面在网上搜索良久,代码都有一些问题,不够完美,今日几经修改,目前效果还比较完美,测试了一些文件,操作结果符合预期,包括一些半透明图片。上代码如下:
import fitz
def replace_images3(input_pdf, output_pdf, image_list):
pdf = fitz.open(input_pdf) # 读取图片
img_id = 0
bbox_dic = {}
for page in range(len(pdf)):
bbox_dic[page] = []
for img in pdf.get_page_images(page):
if not pdf[page].get_image_bbox(img[7]).isEmpty:
bbox_dic[page].append(pdf[page].get_image_bbox(img[7])) # 将位置信息存入dict
pdf._deleteObject(img[0]) # 删除图片
for page in range(len(pdf)):
for i in range(len(bbox_dic[page])):
bbox = bbox_dic[page][i] # 取出位置
fn = image_list[img_id] # 从list中取出新图文件名
pdf[page].insert_image(bbox, filename=fn) # 根据文件名插入图片
img_id += 1
pdf.save(output_pdf) # 保存
测试代码如下:
img_path = "C:\\Users\\eerso\\Desktop\\PDF_PNG\\output\\"
imgs = []
# 下面代码手动生成imgs图片文件列表
for n in range(1, 4):
imgs.append(img_path + str(n) + '.png')
imgs.append(img_path + '4.jpeg')
replace_images3(r"C:\Users\eerso\Desktop\PDF_PNG\new.pdf", r"C:\Users\eerso\Desktop\PDF_PNG\new_x.pdf", imgs)
上面的代码已知缺陷:如果图片有旋转,替换后的图片尺寸会变大且没有旋转,还需要再修改,目前还在研究中…… 2023/7/12
2023/7/17 找到了解决方案参考 https://blog.csdn.net/Crazy_zh/article/details/105346653 可以直接更新pdf中图片数据流
def pdf_rep(pdf_in, pdf_out, img_path):
"""可以正常替换图像数据流,但需要确定图片格式jpeg,png,..."""
import PyPDF4
from io import BytesIO
from PIL import Image
pdf_src = PyPDF4.pdf.PdfFileReader(pdf_in)
pdf_ret = PyPDF4.pdf.PdfFileWriter()
for i in range(0, pdf_src.getNumPages()):
page = pdf_src.getPage(i)
try:
obj = page['/Resources']['/XObject']
for j in obj:
img = obj[j].getData()
with Image.open(img_path) as img:
stream = BytesIO()
img.save(stream, 'png') # 此处应根据图片格式不同而不同
new_image_data = stream.getvalue()
obj[j].setData(new_image_data)
# 上面代码中的obj[j]是一个EncodedStreamObject的实例,在PyPDF4 1.27.0
# 版本中,EncodedStreamObject类中的setData方法并未实现。此版本的发布时间是18年8月,很可能不会再更新了。
#
# 最简单的修改方法:
# 打开PyPDF4模块中的generic.py
# 找到EncodedStreamObject类中的setData方法
# 将方法中的原有代码注释,添加self._data = data
except KeyError as e:
print(f'KeyError:第 {i+1} 页无图')
pdf_ret.addPage(page)
with open(pdf_out, 'wb') as f:
pdf_ret.write(f)

浙公网安备 33010602011771号