You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PDF文件的空白区域自动插入图片签章

如何在PDF文件的空白区域自动插入图片签章

嘿,我来帮你搞定这个自动找空白区插签章的问题!你现在的代码是固定位置插入图片,确实容易和原有内容重叠,要实现自动识别空白区域插入,咱们可以借助PyMuPDF(也就是你用的fitz库)的页面内容分析能力来做。

核心思路

咱们的目标是找到页面上未被原有内容占用、且足够容纳签章图片的区域,步骤很清晰:

  1. 先获取签章图片的实际尺寸,明确我们需要多大的空白空间
  2. 扫描PDF页面上所有已有内容的占位矩形(包括文本、图形等)
  3. 按顺序遍历页面区域,找到第一个能放下图片的空白位置
  4. 把签章图片插入到这个自动定位的位置,同时做个兜底方案防止找不到合适区域

改造后的完整代码

import fitz

def find_blank_area(page, required_width, required_height):
    # 获取当前页面的整体尺寸
    page_rect = page.rect
    # 收集页面上所有已有内容的占位矩形(文本、图形都要算)
    used_rects = []
    
    # 提取所有文本块的矩形区域
    for word in page.get_text("words"):
        word_rect = fitz.Rect(word[:4])
        used_rects.append(word_rect)
    # 提取所有绘图元素的矩形区域(比如线条、形状、已有印章等)
    for drawing in page.get_drawings():
        draw_rect = drawing["rect"]
        used_rects.append(draw_rect)
    
    # 按从上到下、从左到右的顺序扫描页面,找第一个能放下图片的空白区
    step = 10  # 扫描步长,越小越精准但速度稍慢,可按需调整
    x = page_rect.x0
    while x + required_width <= page_rect.x1:
        y = page_rect.y0
        while y + required_height <= page_rect.y1:
            current_rect = fitz.Rect(x, y, x + required_width, y + required_height)
            # 检查当前区域是否和已有内容重叠
            is_overlap = False
            for rect in used_rects:
                if current_rect.intersects(rect):
                    is_overlap = True
                    break
            if not is_overlap:
                return current_rect
            y += step
        x += step
    # 找不到合适区域时返回None,触发兜底逻辑
    return None

# 主执行逻辑
input_file = "example.pdf"
output_file = "example-with-sign.pdf"
image_path = "sign.png"

# 先获取签章图片的实际尺寸,避免硬编码尺寸导致适配问题
with fitz.open(image_path) as img_doc:
    img_page = img_doc[0]
    required_width = img_page.rect.width
    required_height = img_page.rect.height

# 打开目标PDF并处理第一页
file_handle = fitz.open(input_file)
first_page = file_handle[0]

# 自动寻找合适的空白区域
target_rect = find_blank_area(first_page, required_width, required_height)

if target_rect:
    # 读取图片内容并插入到找到的空白区
    img_content = open(image_path, "rb").read()
    first_page.insert_image(target_rect, stream=img_content)
    print(f"成功在位置 {target_rect} 插入签章")
else:
    # 兜底方案:找不到空白区时用你原来的固定位置
    fallback_rect = fitz.Rect(450, 20, 550, 120)
    img_content = open(image_path, "rb").read()
    first_page.insert_image(fallback_rect, stream=img_content)
    print("未找到合适的空白区域,已使用默认位置插入签章")

# 保存修改后的PDF
file_handle.save(output_file)
file_handle.close()

一些实用小提示

  • 你可以调整step参数:步长越小,找到的空白位置越精准,但扫描页面的速度会稍慢,默认10已经能平衡两者
  • 如果想优先找右下角、右上角这类特定位置的空白区,只需要修改find_blank_area里的扫描顺序就行
  • 要是需要给多页PDF批量插签章,套个循环遍历file_handle里的每一页就搞定了

备注:内容来源于stack exchange,提问作者Silvio Júnior

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 14:39:30