从 PDF 中提取文本位置

Extracting text locations from PDF

我正在尝试查找 PDF 中文本元素的位置。为此,我扩展了 PDFTextStripper。我正在使用 multi-page LaTeX-produced PDF 进行测试。

public class TextFinder extends PDFTextStripper {
    private static final Logger logger =
        LoggerFactory.getLogger(TextFinder.class);

    private PDRectangle mediaBox;

    public static class CMProcessor extends OperatorProcessor {

        @Override
        public void process(PDFOperator operator, List<COSBase> arguments)
                throws IOException {

            if ("cm".equals(operator.getOperation())) {
                logger.debug("CM operation");
            }
        }
    }

    private CMProcessor cmProcessor = new CMProcessor();

    public TextFinder() throws IOException {
        this.registerOperatorProcessor("cm", cmProcessor);
    }

    @Override
    protected void startPage(PDPage page) throws IOException {
        super.startPage(page);
        mediaBox = page.findMediaBox();
        logger.debug(String.format("MEDIA (%f,%f) (%f,%f)",
            mediaBox.getLowerLeftX(), mediaBox.getLowerLeftY(),
            mediaBox.getUpperRightX(), mediaBox.getUpperRightY()));
    }

    @Override
    protected void writeString(String text, List<TextPosition> textPositions)
            throws IOException {
        for (TextPosition position : textPositions) {
            float x = position.getXDirAdj();
            float y = mediaBox.getHeight() - position.getYDirAdj();
            logger.debug(String.format("(%f,%f) (%f,%f)", x, y,
                x + position.getWidthDirAdj(), y + position.getHeightDir()));
        }
        super.writeString(text, textPositions);
    }
}

我面临的问题是所有位置似乎都被翻译成 (0, 0) 是最左边最顶层文本元素的坐标:

MEDIA (0.000000,0.000000) (595.270020,841.890015)
(0.000000,0.000000) (11.486961,14.255401)
(11.486961,0.000000) (20.660002,14.255401)
(20.660002,0.000000) (36.733482,14.255401)

感谢mkl,问题是由自定义的OperatorProcessor引起的。没有它它工作得很好。但是我需要运算符处理器,因为我用它来查找图像。我还是不太明白,为什么添加自定义处理器会影响 PDFTextStripper 的行为。

why adding custom processor affects behavior of PDFTextStripper.

原因是您的添加

registerOperatorProcessor("cm", cmProcessor);

实际上替换现有的处理器。原始的对于确定页面上的正确位置很重要。

解决方案是链式处理器。