Java PDFBox 2.0:旋转页面上的不可见线-剪辑路径问题
文件示例: 使用来自主题的优秀解决方案,我尝试提取可见文本。附件中的文本非常小,这可能会导致此剪辑路径问题,其中可能会隐藏部分字母。对于这样的旋转文本,我稍微更改了链接问题的代码:Java PDFBox 2.0:旋转页面上的不可见线-剪辑路径问题,java,pdfbox,Java,Pdfbox,文件示例: 使用来自主题的优秀解决方案,我尝试提取可见文本。附件中的文本非常小,这可能会导致此剪辑路径问题,其中可能会隐藏部分字母。对于这样的旋转文本,我稍微更改了链接问题的代码: @Override protected void processTextPosition(TextPosition text) { PDGraphicsState gs = getGraphicsState();
@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行和其他一些行。
我想知道我的错误在哪里。
提前谢谢 您的PDF出现问题是由以下因素共同造成的
- 文本坐标正好位于剪辑路径边界上李>
- 文本坐标和剪辑路径坐标的不同计算路径具有不同的浮点错误,导致剪辑路径边界上的文本坐标有时被计算为剪辑路径之外的坐标
getTextPositionCenterPoint
仅沿基线居中,因此居中点正好存在字形原点的问题
另一种变通方法效果更好:使用胖点比较。这意味着,我们不检查给定点x,y是否在剪辑区域,而是检查这些坐标周围的小矩形是否与剪辑区域相交。如果由于浮点错误导致坐标偏离剪裁区域,这足以在剪裁区域中找到它们
为此,我们用contains(area,x,y)
替换processTextPosition中的area.contains(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));
}
受保护的布尔包含(面积、浮点x、浮点y){
双倍长度=.0002;
双向上=1.0001;
双向下=.9999;
返回区域.相交(x<0?x*向上:x*向下,y<0?y*向上:y*向下,Math.abs(x*长度),Math.abs(y*长度));
}
(辅助方法)
(实际上,在这里选择围绕坐标的矩形有点随意,这个选择对我很有效。)
通过此更改,我在底部找到了您缺少的第2行、第3行和其他一些行,请参见测试。PDF的问题是由以下因素组合造成的:
- 文本坐标正好位于剪辑路径边界上李>
- 文本坐标和剪辑路径坐标的不同计算路径具有不同的浮点错误,导致剪辑路径边界上的文本坐标有时被计算为剪辑路径之外的坐标
不幸的是,您试图更改这一点在这里没有帮助:问题文本的基线与剪辑路径边界重合,并且您的getTextPositionCenterPoint
仅沿基线居中,因此居中点正好存在字形原点的问题
另一种变通方法效果更好:使用胖点比较。这意味着,我们不检查给定点x,y是否在剪辑区域,而是检查这些坐标周围的小矩形是否与剪辑区域相交。如果由于浮点错误导致坐标偏离剪裁区域,这足以在剪裁区域中找到它们
为此,我们用contains(area,x,y)
替换processTextPosition中的area.contains(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));
}
受保护的布尔包含(面积、浮点x、浮点y){
双倍长度=.0002;
双向上=1.0001;
双向下=.9999;
返回区域.相交(x<0?x*向上:x*向下,y<0?y*向上:y*向下,Math.abs(x*长度),Math.abs(y*长度));
}
(辅助方法)
(实际上,在这里选择围绕坐标的矩形有点随意,这个选择对我很有效。)
通过此更改,我在底部得到了缺少的第2行、第3行和其他一些行,请参见测试。哦,我现在看到了,该区域.contains接受double,但是start.getX()是float。。。谢谢你的解决方案!哦,我现在明白了,area.contains接受double,但是start.getX()是float。。。谢谢你的解决方案!