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

PDFBox 2.0: invisible lines on rotated page - clip path issue

文件示例:click here

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

    @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 中心点(我知道有时这不起作用,因为文本方向,但这里看起来并非如此) 但是在应用这个解决方案之后,由于剪辑路径,我在底部跳过了第二行、第三行和其他一些行。 我想知道我的错误在哪里。 提前致谢!

您的 PDF 问题是由

  • 文本坐标正好在剪辑路径边界上;
  • 文本坐标和剪辑路径坐标的计算路径不同,浮点误差不同,导致剪辑路径边界上的文本坐标有时被计算为剪辑路径外。

不幸的是,您尝试更改此设置在这里无济于事:问题文本的基线与剪辑路径边界重合,而您的 getTextPositionCenterPoint 仅沿基线居中,因此居中点的问题恰好是字形来源有问题。

另一种解决方法效果更好:使用脂肪点比较。这意味着我们不是检查给定点 xy 是否在剪辑区域中,而是检查这些坐标周围的小矩形是否与剪辑区。如果坐标因浮点错误而偏离裁剪区域,这足以在裁剪区域中找到它们。

为此,我们将 processTextPosition 中的 area.contains(x, y) 检查替换为 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辅助方法)

(其实这里选择坐标周围的矩形有点随意,这个选择对我来说很管用。)

通过此更改,我得到了底部缺少的 第 2、第 3 行和其他一些行,请参见。测试 ExtractVisibleText.testFat1.