如何在PDF文件的空白区域自动插入图片签章
如何在PDF文件的空白区域自动插入图片签章
嘿,我来帮你搞定这个自动找空白区插签章的问题!你现在的代码是固定位置插入图片,确实容易和原有内容重叠,要实现自动识别空白区域插入,咱们可以借助PyMuPDF(也就是你用的fitz库)的页面内容分析能力来做。
核心思路
咱们的目标是找到页面上未被原有内容占用、且足够容纳签章图片的区域,步骤很清晰:
- 先获取签章图片的实际尺寸,明确我们需要多大的空白空间
- 扫描PDF页面上所有已有内容的占位矩形(包括文本、图形等)
- 按顺序遍历页面区域,找到第一个能放下图片的空白位置
- 把签章图片插入到这个自动定位的位置,同时做个兜底方案防止找不到合适区域
改造后的完整代码
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
相关产品推荐
相关产品推荐

