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

使用PDFBox 2.0.8如何检测PDF文档中的文本重叠?

嘿,这个问题我熟!用PDFBox 2.0.8检测文本重叠,核心就是抓每个字符的边界框(Bounding Box),然后对比它们的区域是否相交。我给你拆解下具体怎么做:

步骤1:收集每个字符的边界框信息

PDFBox的PDFTextStripper类是解析文本的核心,但默认只会输出文本内容。我们需要继承它,重写processTextPosition方法,把每个字符的位置信息(也就是TextPosition对象)收集起来。每个TextPosition包含了字符的x/y坐标、宽度、高度,这些正是判断重叠需要的关键数据。

步骤2:判断两个字符的边界框是否重叠

拿到所有字符的位置后,我们需要两两对比它们的矩形区域。这里要注意PDF的坐标系:y轴是从页面底部往上递增的,所以字符的下边界是y坐标 - 高度。

判断重叠的逻辑很简单:两个矩形不重叠的情况只有四种——A的右边界≤B的左边界,A的左边界≥B的右边界,A的下边界≥B的上边界,A的上边界≤B的下边界。反过来,如果这四个条件都不满足,就说明两个字符的区域有重叠。

另外,你可以加个阈值过滤误判:比如只有重叠区域超过字符面积的10%,才判定为真正的重叠(避免字体 kerning 导致的微小间距重叠)。

代码实现示例

下面是一个完整的可运行示例,包含了收集字符位置和检测重叠的逻辑:

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class TextOverlapDetector extends PDFTextStripper {
    private final List<TextPosition> allCharacters = new ArrayList<>();

    public TextOverlapDetector() throws IOException {
        super();
    }

    @Override
    protected void processTextPosition(TextPosition textPosition) {
        allCharacters.add(textPosition);
        super.processTextPosition(textPosition);
    }

    // 查找所有重叠的字符对
    public List<OverlappingPair> findOverlappingCharacters() {
        List<OverlappingPair> overlappingPairs = new ArrayList<>();

        // 遍历所有字符对,避免重复对比(i < j)
        for (int i = 0; i < allCharacters.size(); i++) {
            TextPosition charA = allCharacters.get(i);
            for (int j = i + 1; j < allCharacters.size(); j++) {
                TextPosition charB = allCharacters.get(j);
                if (isOverlapping(charA, charB)) {
                    overlappingPairs.add(new OverlappingPair(charA, charB));
                }
            }
        }
        return overlappingPairs;
    }

    // 判断两个字符是否重叠
    private boolean isOverlapping(TextPosition tpA, TextPosition tpB) {
        // 计算字符A的边界框:左、右、上、下
        float aLeft = tpA.getX();
        float aRight = tpA.getX() + tpA.getWidth();
        float aTop = tpA.getY();
        float aBottom = tpA.getY() - tpA.getHeight();

        // 计算字符B的边界框
        float bLeft = tpB.getX();
        float bRight = tpB.getX() + tpB.getWidth();
        float bTop = tpB.getY();
        float bBottom = tpB.getY() - tpB.getHeight();

        // 检查是否不重叠,取反就是重叠
        boolean noOverlap = (aRight <= bLeft) || (aLeft >= bRight) || (aBottom >= bTop) || (aTop <= bBottom);
        return !noOverlap;
    }

    // 辅助类:存储重叠的字符对
    public static class OverlappingPair {
        private final TextPosition char1;
        private final TextPosition char2;

        public OverlappingPair(TextPosition char1, TextPosition char2) {
            this.char1 = char1;
            this.char2 = char2;
        }

        // 打印重叠信息的方法
        public void printInfo() {
            System.out.printf("发现重叠字符:'%s' (位置: X=%.2f, Y=%.2f) 和 '%s' (位置: X=%.2f, Y=%.2f)%n",
                    char1.getUnicode(), char1.getX(), char1.getY(),
                    char2.getUnicode(), char2.getX(), char2.getY());
        }
    }

    // 测试用例
    public static void main(String[] args) {
        try (PDDocument doc = PDDocument.load(new File("your-document.pdf"))) {
            TextOverlapDetector detector = new TextOverlapDetector();
            detector.getText(doc); // 触发文本解析,收集字符位置

            List<OverlappingPair> overlaps = detector.findOverlappingCharacters();
            System.out.println("检测到的重叠字符对数量:" + overlaps.size());
            for (OverlappingPair pair : overlaps) {
                pair.printInfo();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

优化小技巧

  1. 按行分组对比:不同行的字符几乎不会重叠,你可以在processTextPosition里按y坐标分组(同一行的y坐标差异极小,比如设置±1的阈值),只对比同一行内的字符,能大幅减少循环次数,提升效率。
  2. 重叠比例过滤:如果不想把字体间距的微小重叠算进去,可以计算两个矩形的交集面积,除以较小的矩形面积,只有当比例超过你设定的阈值(比如10%)时,才判定为有效重叠。
  3. 忽略空白字符:可以在收集字符时跳过空格、制表符等空白字符,减少不必要的对比。

内容的提问来源于stack exchange,提问作者Susnigdha Chatterjee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:51:35