【问题标题】:PDFBox 2.0: invisible lines on rotated page - clip path issuePDFBox 2.0:旋转页面上的不可见线条 - 剪辑路径问题
【发布时间】:2020-01-26 16:22:11
【问题描述】:

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

【问题讨论】:

    标签: java pdfbox


    【解决方案1】:

    您的 PDF 出现问题是由以下因素共同引起的

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

    不幸的是,您尝试更改这一点在这里没有帮助:问题文本的基线与剪辑路径边框重合,而您的 getTextPositionCenterPoint 仅沿基线居中,因此居中点与字形原点完全一致问题。

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

    为此,我们将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 辅助方法)

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

    有了这个改变,我得到了你缺少的底部的第二行、第三行和其他一些行,参见。测试ExtractVisibleText.testFat1

    【讨论】:

    • 哦,我现在明白了,area.contains 接受 double 但是 start.getX() 是浮动的...感谢您的出色解决方案!
    猜你喜欢
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 2013-11-11
    • 2011-08-08
    • 2016-10-19
    • 2018-12-03
    • 2022-09-29
    • 1970-01-01
    相关资源
    最近更新 更多