PDFBox 2.0:旋转页面上的不可见线条-剪辑路径问题

问题描述 投票:0回答:1

文件示例:click here

使用this主题的出色解决方案,我尝试提取可见文本。附加文档的文本非常小,可能会导致出现此剪切路径问题,其中某些字母可能会被隐藏。对于这种旋转文本,我从链接问题中更改了代码:

    @Override
    protected void processTextPosition(TextPosition text) {
        PDGraphicsState gs = getGraphicsState();                            

        Vector center = getTextPositionCenterPoint(text);
        Area area = gs.getCurrentClippingPath();
        if (area == null || area.contains(lowerLeftX + center.getX(), lowerLeftY + center.getY())) {            
            nonStrokingColors.put(text, gs.getNonStrokingColor());
            renderingModes.put(text, gs.getTextState().getRenderingMode());
            super.processTextPosition(text);
        }
    }


private Vector getTextPositionCenterPoint(TextPosition text) {
        Matrix textMatrix = text.getTextMatrix();
        Vector start = textMatrix.transform(new Vector(0, 0));
        Vector center = null;
        switch (rotation) {
        case 0:
            center = new Vector(start.getX() + text.getWidth()/2, start.getY()); 
            break;
        case 90:
            center = new Vector(start.getX(), start.getY() + text.getWidth()/2);
            break;
        case 180:
            center = new Vector(start.getX() - text.getWidth()/2, start.getY());
            break;
        case 270:
            center = new Vector(start.getX(), start.getY() - text.getWidth()/2);
            break;
        default:
            center = new Vector(start.getX() + text.getWidth()/2, start.getY());
            break;
        }

        return center;
    }

我正在尝试做的事情-根据旋转获得字符X的中心点(我知道有时由于文本方向的原因这是行不通的,但是在这里看起来并非如此)但是应用此解决方案后,由于剪辑路径,我在底部跳过了第二,第三和其他一些行。我想知道我的错误在哪里。预先感谢!

java pdfbox
1个回答
2
投票

PDF的问题是由以下因素引起的

  • 文本坐标正好在剪辑路径边界上;
  • 具有不同浮点错误的文本坐标和剪切路径坐标的不同计算路径,有时会在剪切路径外部计算出剪切路径边界上的文本坐标。

不幸的是,您尝试更改此设置对此无济于事:问题文本的基线与剪切路径边框一致,并且您的getTextPositionCenterPoint仅沿基线居中,因此居中点的问题恰恰是字形原点存在问题。

不同的解决方法效果更好:使用胖点比较。这意味着,我们将检查那些坐标周围的小矩形是否与剪辑区域相交,而不是检查给定点xy是否在剪辑区域中。如果坐标由于浮点错误而从剪辑区域中移出,仍然足以在剪辑区域中找到它们。

为此,我们将area.contains(x, y)中的processTextPosition检查替换为contains(area, x, y),其实现为

protected boolean contains(Area area, float x, float y) {
    double length = .0002;
    double up = 1.0001;
    double down = .9999;
    return area.intersects(x < 0 ? x*up : x*down, y < 0 ? y*up : y*down, Math.abs(x*length), Math.abs(y*length));
}

([PDFVisibleTextStripper辅助方法)

(实际上,此处围绕坐标的矩形的选择有些随意,该选择对我来说很有效。)

通过此更改,我得到了您丢失的第二,第三和底部的其他行,请参见。测试ExtractVisibleText.testFat1

© www.soinside.com 2019 - 2024. All rights reserved.