如何识别和纠正边界框问题?
How to identify and correct Bounding Box issues?
这是一个简单的冒犯pdf。
当我运行 DrawPrintTextLocations下面是我看到的..
但据我了解,当您 select 文本时,边界框(上面的蓝色部分)应该代表显示在任何 pdf reader 中的灰色区域,如下所示。
如果 pdf reader 能够找出要突出显示的灰色区域,那么应该能够找出相同的区域,从而得到字体大小(?)。这个问题是为了让任何人指出正确的方向。
以下是文本 "Test Line." 中 "T" 的详细信息,来自其 TextPosition
对象变量 text
:
72.4801 //text.getXDirAdj()
83.7600 //text.getYDirAdj()
1.0 //text.getFontSize()
50.0 //text.getFontSizeInPt() ::I'm unable to decipher the 50.0
12.0 //text.getXScale() ::Can I assume this to be the font size
8.004 //text.getHeightDir()
7.8984 //text.getWidthOfSpace()
7.1160 //text.getWidthDirAdj()
950.0 //fontDesc.getAscent()
-222.0 //fontDesc.getDescent()
[x=72.4801,y=75.7560,w=7.1160,h=8.0040]
//Red Box boundaries
[x=72.4801,y=46.3560,w=7.1160,h=66.9600] //The height of 66.96 relates to 50 but not sure how?
//Blue Bounding Box boundaries
问题:
1. 边界框问题: 当我调用 font.getBoundingBox()
时似乎不一致。有解决办法吗?
2. getFontSizeInPts(): 这个方法好像是受bounding box的影响。我这样想对吗?(因为Pt中的字体大小显示为50)
3. FontSize的点数有什么方法?
我需要字体大小,因为我的任务是使用不同的字体重新创建 pdf。
这也是一个正确的 pdf 案例,但字体大小显示为 16 而不是最初使用的 12。
对于具有适当边界框的类似 pdf,以下是详细信息:-
以下是文本 "Test Line." 中 "T" 的详细信息,来自其 TextPosition
对象变量 text
:
72.0605 //text.getXDirAdj()
83.3199 //text.getYDirAdj()
16.0 //text.getFontSize() :: Why is this showing 16 while my font is 12 in size
16.0 //text.getFontSizeInPt()
12.0101 //text.getXScale() ::Can I assume this to be the font size
6.6618 //text.getHeightDir()
2.6447 //text.getWidthOfSpace()
7.1193 //text.getWidthDirAdj()
778.808 //fontDesc.getAscent() :: There seems to be an issue with the ascent
-222.1680 //fontDesc.getDescent()
[x=72.0605,y=76.6581,w=7.1193,h=6.6618]
//Red Box boundaries
[x=72.0605,y=72.6176,w=7.1193,h=13.3237] //The height of 13.3237 relates to 12 the font size but not sure how?
//Blue Bounding Box boundaries
使用 MKL 的答案后更新
以下是对我有用的...
//Make Line
Line2D.Float line = new Line2D.Float(0,0,0,1f);
LOG.debug("Line<Before Transform>:" + line.getBounds2D());
s=myTextMatrix.createAffineTransform().createTransformedShape(line);
LOG.debug("Line after AT:"+s.getBounds2D());
s=pageFlipAffineTransform.createTransformedShape(s);
s=pageRotateAffineTransform.createTransformedShape(s);
rect2 = s.getBounds2D();
LOG.debug("Line<After Transform>:" + rect2);
//Font Size
double wi=rect2.getWidth();
double he=rect2.getHeight();
double total=Math.sqrt(wi*wi+he*he);//This is done in case of rotation
long fntSizeinPt = Math.round(total);
LOG.debug("deciphered Font Size is:" + fntSizeinPt);
- Bounding Box Issue: Seems like this is not consistent when I call
font.getBoundingBox()
. Is there a work around for this?
正如评论中已经提到的,我无法完全按照您的描述重现您的观察结果:我也得到了第二个 PDF 的过度扩展的边界框!在这两种情况下,这都与 PDF 中的字体信息一致,字体描述符 FontBBox 值分别为 [-1475 -2463 2867 3117] 和 [-1474.60938 -2463.3789 2867.6758 3116.6992]其中一个非常大,前者似乎是后者的圆形版本。
您提供的第三个 PDF(并将第二个替换为)使用两种字体。用于实际 "Test Line." 字符的字体描述符 FontBBox 值为 [-19 -218 956 891],这些值更正常。因此,DrawPrintTextLocations
在这些字符周围绘制的蓝色框更有意义。第二种字体的 FontBBox 值有点大,[-1462 -813 1723 1134],结果是超出蓝色框的两条蓝线:使用的其他字体的唯一字符是零宽度空间,所以它们周围的框也有零宽度...
因此,仍然一切都是一致的。
一种可能的解决方法是不信任字体的 PDF 表示中的信息,而是检查嵌入的字体程序
- getFontSizeInPts(): This method seems to be influenced by the bounding box. Am I right in thinking so?(As the Font Size in Pt is showing as 50)
没有。您必须知道,在 PDF 中,绘制文本的比例取决于多项:
- 首先是使用Tf指令设置的"font size"和字体;
- 然后是可以放大或缩小这个尺寸的文本矩阵;
- 然后是当前的变换矩阵,它又可以放大或缩小这个尺寸;
- 最后是页面 UserUnit 值,它可以再次放大此大小。
在您的第一个文档中,您的字体大小为 1,文本矩阵可缩放到 50,然后是当前的转换矩阵再次缩小到 12,UserUnit 默认值保持原样。
在您的第二个和第三个文档中,您的字体大小为 16,文本矩阵保持原样,当前转换矩阵缩小为 12,再次由 UserUnit 默认保留。
FontSizeInPts
是您在第二步之后获得的值(嗯,有点,只考虑了文本矩阵的左上角条目)。正如您文件中的情况所示,它本质上只是一个没有进一步兴趣的中间结果。此外,边界框没有参与其计算。
- What is the way to get FontSize in points?
IMO 你应该取一条与字体大小值一样长的垂直线,应用文本矩阵和当前转换矩阵,取结果线的长度并将其乘以页面 UserUnit值。
TextPosition
的 TextMatrix
值已经结合了其中的一些步骤;尽管它的名字是 而不是 PDF 规范中指定的文本矩阵,但更多,请参见。它的文档:
/**
* The matrix containing the starting text position and scaling. Despite the name, it is not the
* text matrix set by the "Tm" operator, it is really the effective text rendering matrix (which
* is dependent on the current transformation matrix (set by the "cm" operator), the text matrix
* (set by the "Tm" operator), the font size (set by the "Tf" operator) and the page cropbox).
*
* @return The Matrix containing the starting text position
*/
public Matrix getTextMatrix()
因此,如果m
是Matrix
,你只需要将它应用到点(0, 0)和(0, 1),将矩阵应用到它们,测量结果点的距离,并将该距离乘以页面 UserUnit 值(通常是 1
)。
这是一个简单的冒犯pdf。
当我运行 DrawPrintTextLocations下面是我看到的..
但据我了解,当您 select 文本时,边界框(上面的蓝色部分)应该代表显示在任何 pdf reader 中的灰色区域,如下所示。
如果 pdf reader 能够找出要突出显示的灰色区域,那么应该能够找出相同的区域,从而得到字体大小(?)。这个问题是为了让任何人指出正确的方向。
以下是文本 "Test Line." 中 "T" 的详细信息,来自其 TextPosition
对象变量 text
:
72.4801 //text.getXDirAdj()
83.7600 //text.getYDirAdj()
1.0 //text.getFontSize()
50.0 //text.getFontSizeInPt() ::I'm unable to decipher the 50.0
12.0 //text.getXScale() ::Can I assume this to be the font size
8.004 //text.getHeightDir()
7.8984 //text.getWidthOfSpace()
7.1160 //text.getWidthDirAdj()
950.0 //fontDesc.getAscent()
-222.0 //fontDesc.getDescent()
[x=72.4801,y=75.7560,w=7.1160,h=8.0040]
//Red Box boundaries
[x=72.4801,y=46.3560,w=7.1160,h=66.9600] //The height of 66.96 relates to 50 but not sure how?
//Blue Bounding Box boundaries
问题:
1. 边界框问题: 当我调用 font.getBoundingBox()
时似乎不一致。有解决办法吗?
2. getFontSizeInPts(): 这个方法好像是受bounding box的影响。我这样想对吗?(因为Pt中的字体大小显示为50)
3. FontSize的点数有什么方法?
我需要字体大小,因为我的任务是使用不同的字体重新创建 pdf。
这也是一个正确的 pdf 案例,但字体大小显示为 16 而不是最初使用的 12。
对于具有适当边界框的类似 pdf,以下是详细信息:-
以下是文本 "Test Line." 中 "T" 的详细信息,来自其 TextPosition
对象变量 text
:
72.0605 //text.getXDirAdj()
83.3199 //text.getYDirAdj()
16.0 //text.getFontSize() :: Why is this showing 16 while my font is 12 in size
16.0 //text.getFontSizeInPt()
12.0101 //text.getXScale() ::Can I assume this to be the font size
6.6618 //text.getHeightDir()
2.6447 //text.getWidthOfSpace()
7.1193 //text.getWidthDirAdj()
778.808 //fontDesc.getAscent() :: There seems to be an issue with the ascent
-222.1680 //fontDesc.getDescent()
[x=72.0605,y=76.6581,w=7.1193,h=6.6618]
//Red Box boundaries
[x=72.0605,y=72.6176,w=7.1193,h=13.3237] //The height of 13.3237 relates to 12 the font size but not sure how?
//Blue Bounding Box boundaries
使用 MKL 的答案后更新
以下是对我有用的...
//Make Line
Line2D.Float line = new Line2D.Float(0,0,0,1f);
LOG.debug("Line<Before Transform>:" + line.getBounds2D());
s=myTextMatrix.createAffineTransform().createTransformedShape(line);
LOG.debug("Line after AT:"+s.getBounds2D());
s=pageFlipAffineTransform.createTransformedShape(s);
s=pageRotateAffineTransform.createTransformedShape(s);
rect2 = s.getBounds2D();
LOG.debug("Line<After Transform>:" + rect2);
//Font Size
double wi=rect2.getWidth();
double he=rect2.getHeight();
double total=Math.sqrt(wi*wi+he*he);//This is done in case of rotation
long fntSizeinPt = Math.round(total);
LOG.debug("deciphered Font Size is:" + fntSizeinPt);
- Bounding Box Issue: Seems like this is not consistent when I call
font.getBoundingBox()
. Is there a work around for this?
正如评论中已经提到的,我无法完全按照您的描述重现您的观察结果:我也得到了第二个 PDF 的过度扩展的边界框!在这两种情况下,这都与 PDF 中的字体信息一致,字体描述符 FontBBox 值分别为 [-1475 -2463 2867 3117] 和 [-1474.60938 -2463.3789 2867.6758 3116.6992]其中一个非常大,前者似乎是后者的圆形版本。
您提供的第三个 PDF(并将第二个替换为)使用两种字体。用于实际 "Test Line." 字符的字体描述符 FontBBox 值为 [-19 -218 956 891],这些值更正常。因此,DrawPrintTextLocations
在这些字符周围绘制的蓝色框更有意义。第二种字体的 FontBBox 值有点大,[-1462 -813 1723 1134],结果是超出蓝色框的两条蓝线:使用的其他字体的唯一字符是零宽度空间,所以它们周围的框也有零宽度...
因此,仍然一切都是一致的。
一种可能的解决方法是不信任字体的 PDF 表示中的信息,而是检查嵌入的字体程序
- getFontSizeInPts(): This method seems to be influenced by the bounding box. Am I right in thinking so?(As the Font Size in Pt is showing as 50)
没有。您必须知道,在 PDF 中,绘制文本的比例取决于多项:
- 首先是使用Tf指令设置的"font size"和字体;
- 然后是可以放大或缩小这个尺寸的文本矩阵;
- 然后是当前的变换矩阵,它又可以放大或缩小这个尺寸;
- 最后是页面 UserUnit 值,它可以再次放大此大小。
在您的第一个文档中,您的字体大小为 1,文本矩阵可缩放到 50,然后是当前的转换矩阵再次缩小到 12,UserUnit 默认值保持原样。
在您的第二个和第三个文档中,您的字体大小为 16,文本矩阵保持原样,当前转换矩阵缩小为 12,再次由 UserUnit 默认保留。
FontSizeInPts
是您在第二步之后获得的值(嗯,有点,只考虑了文本矩阵的左上角条目)。正如您文件中的情况所示,它本质上只是一个没有进一步兴趣的中间结果。此外,边界框没有参与其计算。
- What is the way to get FontSize in points?
IMO 你应该取一条与字体大小值一样长的垂直线,应用文本矩阵和当前转换矩阵,取结果线的长度并将其乘以页面 UserUnit值。
TextPosition
的 TextMatrix
值已经结合了其中的一些步骤;尽管它的名字是 而不是 PDF 规范中指定的文本矩阵,但更多,请参见。它的文档:
/**
* The matrix containing the starting text position and scaling. Despite the name, it is not the
* text matrix set by the "Tm" operator, it is really the effective text rendering matrix (which
* is dependent on the current transformation matrix (set by the "cm" operator), the text matrix
* (set by the "Tm" operator), the font size (set by the "Tf" operator) and the page cropbox).
*
* @return The Matrix containing the starting text position
*/
public Matrix getTextMatrix()
因此,如果m
是Matrix
,你只需要将它应用到点(0, 0)和(0, 1),将矩阵应用到它们,测量结果点的距离,并将该距离乘以页面 UserUnit 值(通常是 1
)。