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

如何区分PDF背景色与文本色并通过PDFBox修复不可见文本

使用PDFBox修复PDF文本与背景同色不可见问题

核心思路

PDF中出现文本与背景同色不可见的情况,本质是文本的非描边/描边颜色和背景填充颜色一致。我们可以通过解析PDF流提取文本对象,重建PDF时强制重置文本颜色的方式,让文本可见。

具体实现步骤

1. 提取文本对象信息(可选,用于确认不可见文本)

通过继承PDFStreamEngine,拦截文本绘制操作符,记录文本的内容、位置、当前颜色等信息到自定义的TextObjectInfo类中:

public class TextObjectExtractor extends PDFStreamEngine {
    private final List<TextObjectInfo> textInfos = new ArrayList<>();

    public TextObjectExtractor() throws IOException {
        super();
        // 注册文本相关操作符处理器
        addOperator(new ShowText());
        addOperator(new ShowTextAdjusted());
        addOperator(new SetTextFont());
        addOperator(new SetTextColor());
    }

    @Override
    protected void processOperator(Operator operator, List<COSBase> operands) throws IOException {
        String opName = operator.getName();
        // 捕获所有文本绘制操作
        if ("Tj".equals(opName) || "'".equals(opName) || "\"".equals(opName) || "TJ".equals(opName)) {
            PDGraphicsState gs = getGraphicsState();
            PDColor textColor = gs.getNonStrokingColor();
            // 填充TextObjectInfo的属性(文本内容、位置矩阵、颜色等)
            textInfos.add(new TextObjectInfo(/* 传入对应参数 */));
        }
        super.processOperator(operator, operands);
    }

    public List<TextObjectInfo> getTextInfos() {
        return textInfos;
    }
}

2. 自定义PDF重建器,强制设置文本颜色

编写SimplePdfRegenerator类,在重建PDF流时,拦截文本绘制操作,强制将文本颜色设置为固定值(比如黑色),同时保留原有背景绘制逻辑:

public class SimplePdfRegenerator extends PDFStreamEngine {
    private final PDPageContentStream contentStream;
    // 固定文本颜色:黑色(RGB值[0,0,0])
    private final PDColor FIXED_TEXT_COLOR = new PDColor(new float[]{0, 0, 0}, PDDeviceRGB.INSTANCE);

    public SimplePdfRegenerator(PDPage page, PDPageContentStream contentStream) throws IOException {
        super();
        this.contentStream = contentStream;
        // 拦截文本颜色设置与绘制操作
        addOperator(new SetTextColor());
        // 处理单个文本绘制操作Tj
        addOperator(new ShowText() {
            @Override
            public void process(Operator operator, List<COSBase> operands) throws IOException {
                // 绘制文本前强制设置固定颜色
                contentStream.setNonStrokingColor(FIXED_TEXT_COLOR);
                // 执行原文本绘制逻辑
                super.process(operator, operands);
            }
        });
        // 处理多行文本绘制操作TJ
        addOperator(new ShowTextAdjusted() {
            @Override
            public void process(Operator operator, List<COSBase> operands) throws IOException {
                contentStream.setNonStrokingColor(FIXED_TEXT_COLOR);
                super.process(operator, operands);
            }
        });
        // 处理其他文本快捷操作符'和"
        addOperator(new OperatorProcessor() {
            @Override
            public void process(Operator operator, List<COSBase> operands) throws IOException {
                contentStream.setNonStrokingColor(FIXED_TEXT_COLOR);
                // 调用默认处理器执行原操作
                OperatorProcessor defaultProcessor = new OperatorProcessor();
                defaultProcessor.process(operator, operands);
            }
        });
    }

    @Override
    protected void processOperator(Operator operator, List<COSBase> operands) throws IOException {
        // 保留背景、路径等非文本操作的原有逻辑
        super.process(operator, operands);
    }
}

3. 执行PDF修复流程

加载原始PDF,遍历页面提取文本信息(可选),然后用重建器生成新的PDF:

public class PdfFixer {
    public static void main(String[] args) throws IOException {
        File inputFile = new File("input.pdf");
        File outputFile = new File("fixed_output.pdf");

        try (PDDocument document = PDDocument.load(inputFile)) {
            for (PDPage page : document.getPages()) {
                // 可选:提取文本信息,排查不可见文本
                TextObjectExtractor extractor = new TextObjectExtractor();
                extractor.processPage(page);
                List<TextObjectInfo> textInfos = extractor.getTextInfos();

                // 重建页面内容,强制设置文本颜色
                try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.OVERWRITE, true, true)) {
                    SimplePdfRegenerator regenerator = new SimplePdfRegenerator(page, contentStream);
                    regenerator.processPage(page);
                }
            }
            document.save(outputFile);
        }
    }
}

效果验证

对比修复前后的文档状态:

  • 原始背景:原始PDF背景
  • 无背景文本(黑色):无背景黑色文本
  • 输入文档(文本可见状态):输入文档(文本可见)
  • 修复前输出(文本银色不可见):修复前输出(文本不可见)
  • 修复后输出(文本为固定黑色,可见):修复后输出(文本可见)

内容的提问来源于stack exchange,提问作者Nitish Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:33:35