Python批量修改pdf中的固定位置的图片

功能

首先,这份代码的功能是批量修改pdf文件中的一个固定位置图像,可用于修改水印,或用其他图片覆盖。

缺点:这是用图片覆盖的方式,不能保留覆盖位置的文本内容,不能去除复杂水印。

整体代码

import os
import fitz  # PyMuPDF
import logging
import tkinter as tk
from tkinter import simpledialog, filedialog, messagebox
from tkinter import PhotoImage

# 配置日志记录
logging.basicConfig(filename='process_pdfs.log', level=logging.DEBUG,
                    format='%(asctime)s - %(levelname)s - %(message)s')


def convert_color_to_range(color):
    return tuple(c / 255.0 for c in color)


def remove_watermark_from_pdf(input_pdf, output_pdf, rect, image_path=None, color=(255, 255, 255)):
    try:
        doc = fitz.open(input_pdf)
        for page_num in range(len(doc)):
            page = doc.load_page(page_num)
            shape = page.new_shape()

            if image_path:
                # 插入图片,并调整大小以适应指定的矩形区域
                img = fitz.open(image_path)
                img_rect = fitz.Rect(rect)  # 创建一个与矩形区域大小相同的 Rect 对象
                page.insert_image(img_rect, filename=image_path, keep_proportion=False)
            else:
                # 否则覆盖区域颜色
                if shape is None:
                    raise ValueError("Shape object creation failed")

                shape.draw_rect(rect)
                color_converted = convert_color_to_range(color)
                shape.finish(color=color_converted, fill=color_converted)
                shape.commit()

        doc.save(output_pdf, deflate=True)
        logging.info(f"Processed {input_pdf} and saved to {output_pdf}")
    except Exception as e:
        logging.error(f"Failed to process {input_pdf}: {e}")


def process_pdfs_in_folder(input_folder, output_folder, rect, image_path=None, color=(255, 255, 255)):
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.pdf'):
            input_pdf = os.path.join(input_folder, filename)
            output_pdf = os.path.join(output_folder, f"processed_{filename}")
            logging.info(f"Processing {input_pdf}...")
            remove_watermark_from_pdf(input_pdf, output_pdf, rect, image_path, color)
            logging.info(f"Saved to {output_pdf}")


def get_rect_from_user():
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口

    # 通过弹窗获取用户输入
    x0 = simpledialog.askinteger("输入", "请输入左上角 x 坐标:")
    y0 = simpledialog.askinteger("输入", "请输入左上角 y 坐标:")
    x1 = simpledialog.askinteger("输入", "请输入右下角 x 坐标:")
    y1 = simpledialog.askinteger("输入", "请输入右下角 y 坐标:")

    return (x0, y0, x1, y1)


def ask_for_image_replacement():
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口

    # 弹窗询问是否要替换成其他图片
    replace = messagebox.askyesno("替换图片", "是否要替换为其他图片?")

    if replace:
        # 选择图片文件
        image_path = filedialog.askopenfilename(title="选择图片", filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")])
        if image_path:
            # 使用 tkinter 的 PhotoImage 检查图片大小
            img = PhotoImage(file=image_path)
            if img.width() <= 1024 and img.height() <= 1024:
                return image_path
            else:
                messagebox.showerror("错误", "选择的图片尺寸必须在 1024x1024 像素内。")
                return None
    return None


if __name__ == "__main__":
    input_folder = os.path.abspath("需要加工的pdf")
    output_folder = os.path.abspath("完成加工")

    logging.info(f"Input folder: {input_folder}")
    logging.info(f"Output folder: {output_folder}")

    if not os.path.exists(input_folder):
        logging.error(f"Input folder '{input_folder}' does not exist.")
    if not os.path.exists(output_folder):
        logging.error(f"Output folder '{output_folder}' does not exist.")

    # 通过弹窗获取用户输入的矩形区域
    rect = get_rect_from_user()

    # 询问用户是否要替换为其他图片
    image_path = ask_for_image_replacement()

    process_pdfs_in_folder(input_folder, output_folder, rect, image_path)

    logging.info("Processing completed.")

    input("Press Enter to exit...")

使用介绍

此代码需要打包成.exe文件才可使用

将需要加工的pdf放进对应文件夹,运行.exe即可

pdf图片坐标信息:例如100*100的图片,左上角就是(0,0),右下角就是(100,100),如果需要替换成其他图片,源代码有1k分辨率的限制,不需要就直接替换成白色。

代码逻辑

库:

fitz是用于处理PDF文件
logging是记录修改日志
tkinter创建修改用户界面的弹窗
PhotoImage是用作图像文件处理

颜色转换函数

def convert_color_to_range(color):
    return tuple(c / 255.0 for c in color)

功能:将RGB颜色值从[0,255]范围转换为[0,1]范围,以便PYMuPDF使用。

从PDF中覆盖指定位置的图片

def remove_watermark_from_pdf(input_pdf, output_pdf, rect, image_path=None, color=(255, 255, 255)):
    try:
        doc = fitz.open(input_pdf)
        for page_num in range(len(doc)):
            page = doc.load_page(page_num)
            shape = page.new_shape()

            if image_path:
                img = fitz.open(image_path)
                img_rect = fitz.Rect(rect)
                page.insert_image(img_rect, filename=image_path, keep_proportion=False)
            else:
                if shape is None:
                    raise ValueError("Shape object creation failed")

                shape.draw_rect(rect)
                color_converted = convert_color_to_range(color)
                shape.finish(color=color_converted, fill=color_converted)
                shape.commit()

        doc.save(output_pdf, deflate=True)
        logging.info(f"Processed {input_pdf} and saved to {output_pdf}")
    except Exception as e:
        logging.error(f"Failed to process {input_pdf}: {e}")

功能:加工输入的pdf

参数:input_pdf :输入PDF路径
        output_pdf :输出PDF路径
        rect : 要覆盖的区域,格式为(x0,y0,x1,y1)。
        image_path : 用于替换的图片路径(如果有需要替换图片)
        color : 用于填充矩形的区域颜色(默认白色)

逻辑

打开 PDF 文件并遍历每一页。

如果提供了图片路径,则插入图片并调整大小以适应指定区域。

如果没有提供图片,则用指定颜色填充矩形区域。

保存处理后的 PDF 文件。

记录处理状态。

处理文件夹中的PDF文件

def process_pdfs_in_folder(input_folder, output_folder, rect, image_path=None, color=(255, 255, 255)):
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.pdf'):
            input_pdf = os.path.join(input_folder, filename)
            output_pdf = os.path.join(output_folder, f"processed_{filename}")
            logging.info(f"Processing {input_pdf}...")
            remove_watermark_from_pdf(input_pdf, output_pdf, rect, image_path, color)
            logging.info(f"Saved to {output_pdf}")

功能就是处理文件夹下的所有pdf文件,并将处理好的文件全部保存到另一个文件夹中。

参数:

input_folder : 待处理DPF文件夹路径(需要加工的pdf)
output_folder : 处理后的PDF保存路径
rect :需要覆盖的位置区域。
image_path : 图片路径
color : 用于填充矩形的颜色

获取用户输入的矩形区域:

def get_rect_from_user():
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口

    # 通过弹窗获取用户输入
    x0 = simpledialog.askinteger("输入", "请输入左上角 x 坐标:")
    y0 = simpledialog.askinteger("输入", "请输入左上角 y 坐标:")
    x1 = simpledialog.askinteger("输入", "请输入右下角 x 坐标:")
    y1 = simpledialog.askinteger("输入", "请输入右下角 y 坐标:")

    return (x0, y0, x1, y1)

作用供用户输入矩形坐标。

替换图片

def ask_for_image_replacement():
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口

    # 弹窗询问是否要替换成其他图片
    replace = messagebox.askyesno("替换图片", "是否要替换为其他图片?")

    if replace:
        # 选择图片文件
        image_path = filedialog.askopenfilename(title="选择图片", filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")])
        if image_path:
            # 使用 tkinter 的 PhotoImage 检查图片大小
            img = PhotoImage(file=image_path)
            if img.width() <= 1024 and img.height() <= 1024:
                return image_path
            else:
                messagebox.showerror("错误", "选择的图片尺寸必须在 1024x1024 像素内。")
                return None
    return None

功能:是否要用图片替换,当然这里的图片大小可以自己改

主要执行程序:

if __name__ == "__main__":
    input_folder = os.path.abspath("需要加工的pdf")
    output_folder = os.path.abspath("完成加工")

    logging.info(f"Input folder: {input_folder}")
    logging.info(f"Output folder: {output_folder}")

    if not os.path.exists(input_folder):
        logging.error(f"Input folder '{input_folder}' does not exist.")
    if not os.path.exists(output_folder):
        logging.error(f"Output folder '{output_folder}' does not exist.")

    # 通过弹窗获取用户输入的矩形区域
    rect = get_rect_from_user()

    # 询问用户是否要替换为其他图片
    image_path = ask_for_image_replacement()

    process_pdfs_in_folder(input_folder, output_folder, rect, image_path)

    logging.info("Processing completed.")

    input("Press Enter to exit...")

逻辑:设置输入和输出文件夹绝对路径,记录输入和输出文件夹的路径,通过弹窗获取矩形区域坐标,是否需要用图片替换,处理文件夹下的所有PDF文件,最后记录结果日志。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值