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

如何将PyPDF4修改PDF黑色对象颜色的代码迁移到pypdf 3.6.0?

迁移PyPDF4到pypdf 3.6.0:PDF黑色对象转红色实现指引

核心逻辑说明

pypdf 3.x版本对PDF内容流的操作机制和PyPDF4差异明显,不能直接沿用旧版的字符串替换或简单流操作,必须通过解析内容流的指令单元,针对性替换颜色设置指令,再重新绑定到页面。

具体实现步骤

1. 导入依赖模块

from pypdf import PdfReader, PdfWriter
from pypdf.generic import ContentStream, NameObject, NumberObject

2. 编写颜色替换函数

遍历内容流的每一组指令,识别所有设置黑色的操作(包含RGB模式和灰度模式的填充、描边色),替换为红色设置指令:

def replace_black_with_red(content_stream):
    new_operations = []
    # 遍历内容流的所有指令对(操作数列表 + 操作符)
    for operands, operator in content_stream.operations:
        # 替换RGB填充黑色(指令rg)
        if operator == b"rg" and operands == [NumberObject(0), NumberObject(0), NumberObject(0)]:
            new_operations.append(([NumberObject(1), NumberObject(0), NumberObject(0)], b"rg"))
        # 替换RGB描边黑色(指令RG)
        elif operator == b"RG" and operands == [NumberObject(0), NumberObject(0), NumberObject(0)]:
            new_operations.append(([NumberObject(1), NumberObject(0), NumberObject(0)], b"RG"))
        # 替换灰度填充黑色(指令g),转为RGB红色填充
        elif operator == b"g" and operands == [NumberObject(0)]:
            new_operations.append(([NumberObject(1), NumberObject(0), NumberObject(0)], b"rg"))
        # 替换灰度描边黑色(指令G),转为RGB红色描边
        elif operator == b"G" and operands == [NumberObject(0)]:
            new_operations.append(([NumberObject(1), NumberObject(0), NumberObject(0)], b"RG"))
        # 非颜色设置指令直接保留
        else:
            new_operations.append((operands, operator))
    # 用新指令重新构建内容流
    return ContentStream(new_operations, content_stream.pdf)

3. 处理PDF并生成输出

读取源PDF的每个页面,替换内容流后绑定到页面,最终写入输出文件:

def process_pdf(input_file, output_file):
    reader = PdfReader(input_file)
    writer = PdfWriter()

    for page in reader.pages:
        # 解析当前页面的内容流
        original_stream = ContentStream(page["/Contents"], reader)
        # 执行颜色替换
        modified_stream = replace_black_with_red(original_stream)
        # 将修改后的内容流重新绑定到页面
        page[NameObject("/Contents")] = modified_stream
        # 添加处理后的页面到写入器
        writer.add_page(page)

    # 写入最终PDF文件
    with open(output_file, "wb") as f:
        writer.write(f)

# 调用示例
process_pdf("source.pdf", "red_output.pdf")

关键差异提示

  • PyPDF4中直接操作ContentStream字符串的方式在pypdf 3.x中不再适用,必须通过operations属性拆解指令单元。
  • 页面内容流的赋值需要通过NameObject("/Contents")明确指定,确保修改后的内容被页面正确识别。
  • 字符串替换容易因PDF内容流压缩、指令拆分等问题失效,解析指令的方式才是可靠方案。

内容的提问来源于stack exchange,提问作者Albin Dennevi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 16:32:13