PDFBox:提取图像位置(错误的 x 和 y)
PDFBox: extract image location (wrong x and y)
各位程序员大家好。
我可以正确提取PDF文本坐标及其格式。但我不能用图像来做。我可以获得正确的宽度和高度,但它给了我错误的 x 和 y.
我正在使用 Photoshop 检查是否获得了正确的 x、y、width, height 坐标, 但只有 width 和 height 是正确的
这是我的代码:
@Override
public void processOperator(Operator operator, List<COSBase> arguments) throws IOException {
if ("cm".equals(operator.getName())) {
float width = ((COSNumber)arguments.get(0)).floatValue();
float height = ((COSNumber)arguments.get(3)).floatValue();
float x = ((COSNumber)arguments.get(4)).floatValue();
float y = ((COSNumber)arguments.get(5)).floatValue();
System.out.println("w: " + width + " h: " + height + " x: " + x + " y: " + y);
// process image coordinates
}
super.processOperator(operator, arguments);
}
这是我使用的示例 PDF:
http://persci.mit.edu/pub_pdfs/personal_photo_enhancement.pdf
我正在使用第 2 页。
这是程序的输出:
w: 503.87997 h: 152.64 x: 71.5168 y: 561.056
我使用 Photoshop 创建了一个矩形并叠加图像,但只有宽度和高度是正确的。
另一个问题
我使用了这个 PDF
http://www.ctex.org/documents/shredder/src/example.pdf
我用的是第17页
为什么PDF显示的坐标很多,而PDF中的图片只有一个?
w: 1.0 h: 1.0 x: 124.802 y: 776.998
w: 1.0 h: 1.0 x: 0.0 y: 3.587
w: 1.0 h: 1.0 x: 0.0 y: -3.985
w: 1.0 h: 1.0 x: 343.711 y: 0.398
w: 1.0 h: 1.0 x: -343.711 y: -24.906
w: 1.0 h: 1.0 x: 147.972 y: -106.0
w: 1.0 h: 1.0 x: 0.0 y: 0.0
w: 1.0 h: 1.0 x: 0.0 y: 0.0
w: 0.1 h: 0.1 x: 0.0 y: 0.0
w: 1.0 h: 1.0 x: 45.0 y: 0.0
w: 1.0 h: 1.0 x: -79.37 y: -21.918
w: 1.0 h: 1.0 x: 116.507 y: 0.0
w: 1.0 h: 1.0 x: -230.109 y: -2.145
w: 1.0 h: 1.0 x: 0.0 y: -20.324
w: 1.0 h: 1.0 x: 0.0 y: -13.682
w: 1.0 h: 1.0 x: 3.387 y: 2.989
w: 1.0 h: 1.0 x: 20.175 y: -2.989
w: 1.0 h: 1.0 x: -23.562 y: -0.398
w: 1.0 h: 1.0 x: 30.685 y: 3.387
w: 1.0 h: 1.0 x: 179.886 y: -66.21
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: -215.552 y: -17.195
w: 1.0 h: 1.0 x: 0.0 y: -13.682
w: 1.0 h: 1.0 x: 3.387 y: 2.989
w: 1.0 h: 1.0 x: 20.175 y: -2.989
w: 1.0 h: 1.0 x: -23.562 y: -0.398
w: 1.0 h: 1.0 x: 30.685 y: 3.387
w: 1.0 h: 1.0 x: -35.666 y: -76.173
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: -4.981 y: -41.843
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: -4.981 y: -51.806
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: 175.592 y: -19.925
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: -185.554 y: -19.925
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: 0.0 y: -37.121
w: 1.0 h: 1.0 x: 0.0 y: -13.682
w: 1.0 h: 1.0 x: 3.387 y: 2.989
w: 1.0 h: 1.0 x: 20.175 y: -2.989
w: 1.0 h: 1.0 x: -23.562 y: -0.398
w: 1.0 h: 1.0 x: 30.685 y: 3.387
w: 1.0 h: 1.0 x: 282.916 y: -18.389
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: -318.582 y: -17.196
w: 1.0 h: 1.0 x: 0.0 y: -13.682
w: 1.0 h: 1.0 x: 3.387 y: 2.989
w: 1.0 h: 1.0 x: 20.175 y: -2.989
w: 1.0 h: 1.0 x: -23.562 y: -0.398
w: 1.0 h: 1.0 x: 30.685 y: 3.387
w: 1.0 h: 1.0 x: 11.988 y: -11.216
w: 1.0 h: 1.0 x: 0.0 y: -14.833
w: 1.0 h: 1.0 x: 3.388 y: 4.926
w: 1.0 h: 1.0 x: 60.357 y: -4.926
w: 1.0 h: 1.0 x: -63.745 y: -0.399
w: 1.0 h: 1.0 x: 63.944 y: -3.985
w: 1.0 h: 1.0 x: -59.959 y: 0.0
w: 1.0 h: 1.0 x: 64.143 y: 0.0
w: 1.0 h: 1.0 x: -110.801 y: -13.101
w: 1.0 h: 1.0 x: 0.0 y: -2.241
w: 1.0 h: 1.0 x: 39.308 y: 2.241
w: 1.0 h: 1.0 x: 0.0 y: -2.241
w: 1.0 h: 1.0 x: -37.066 y: 0.0
w: 1.0 h: 1.0 x: 0.0 y: 13.294
w: 1.0 h: 1.0 x: 1.145 y: -9.907
w: 1.0 h: 1.0 x: 39.641 y: 11.302
w: 1.0 h: 1.0 x: 0.0 y: -15.686
w: 1.0 h: 1.0 x: 1.693 y: 14.291
w: 1.0 h: 1.0 x: 0.0 y: -12.896
w: 1.0 h: 1.0 x: 3.288 y: 2.989
w: 1.0 h: 1.0 x: 47.544 y: -2.989
w: 1.0 h: 1.0 x: -50.832 y: -0.299
w: 1.0 h: 1.0 x: 52.227 y: -1.096
w: 1.0 h: 1.0 x: -53.92 y: -0.597
w: 1.0 h: 1.0 x: 57.838 y: 14.888
w: 1.0 h: 1.0 x: 0.0 y: -11.22
w: 1.0 h: 1.0 x: 0.0 y: -2.473
w: 1.0 h: 1.0 x: 42.751 y: 2.473
w: 1.0 h: 1.0 x: 0.0 y: -2.473
w: 1.0 h: 1.0 x: -40.278 y: 0.0
w: 1.0 h: 1.0 x: 0.0 y: 13.693
w: 1.0 h: 1.0 x: 1.313 y: -9.907
w: 1.0 h: 1.0 x: -104.652 y: -78.762
w: 1.0 h: 1.0 x: 166.874 y: 0.0
w: 1.0 h: 1.0 x: 176.837 y: 0.0
问题的原因
您的代码不是真正寻找图像位置和大小,只是在友好的环境下它会找到它们。
您的代码只显示了一个没有明确上下文的方法(我想这就是为什么没有人认真分析该代码并发现问题的原因)。
考虑到上下文(PDFBox,内容流分析),我假设您创建了一个运算符处理器class,您在其中覆盖了processOperator
方法根据发布的代码。此外,我假设, 您使用某些 PDF 流引擎为 cm 指令注册了运算符处理器,并且 运行 针对您的样本 PDF .
鉴于这些假设,很清楚为什么您的运算符处理器的输出有时只包含图像大小和位置,但通常包含许多不相关的数据集:
指令cm的作用只是改变当前t运行sformation矩阵,与绘图没有直接或单一的关系位图图片!
赋予PDF规范:
Operands
Operator
Description
a b c d e f
cm
Modify the current transformation matrix (CTM) by concatenating the specified matrix (see 8.3.2, "Coordinate Spaces"). Although the operands specify a matrix, they shall be written as six separate numbers, not as an array.
(Table 57 – 图形状态运算符 – ISO 32000-1)
cm 参数偶尔包含图像大小和位置信息的唯一原因是位图绘制操作符将图像绘制到 1x1 区域(在用户 space unit) 其左下角为原点,并拉伸和移动坐标系,使该区域最终对应于结果页面上所需的图像大小,PDF 处理器修改当前的 t运行sformation 矩阵因此在绘制图像之前使用 cm 指令,通常就在之前。
如果他们在一个步骤中这样做(如上所述cm 将指定的矩阵连接到CTM,它会不替换它)并且不使用旋转或类似的细节,a和d(第一个和第四个cm参数)确实包含页面上图像的大小(默认用户space单位)和e和f(第五个和第六个cm参数)包含其左下角的坐标。
如何正确操作
因此,不仅要查看 cm 参数,还必须
- 解析有问题的内容流,
- 计算应用于 CTM 的所有矩阵的串联(同时跟踪中间 q 和 Q 指令的影响),和
- 当位图图像资源的Do指令发生时,检索当前t运行信息矩阵的值。
幸运的是,如果您愿意,PDFBox 已经为您完成了所有繁重的工作,请参见。 PrintImageLocations
个示例位于
- (对于 PDFBox 1.8.13)https://svn.apache.org/repos/asf/pdfbox/tags/1.8.13/examples/src/main/java/org/apache/pdfbox/examples/util/PrintImageLocations.java
- (对于 PDFBox 2.0.3)https://svn.apache.org/repos/asf/pdfbox/tags/2.0.3/examples/src/main/java/org/apache/pdfbox/examples/util/PrintImageLocations.java
关于您的问题
就 PDF 坐标系而言,您为 "personal_photo_enhancement.pdf" 第 2 页获得的坐标是正确的。可能是 Photoshop 使用了不同的坐标系,或者您检查了错误的图像角。
"example.pdf" 第 17 页的输出非常多,因为该 PDF 使用 CTM 操作,不仅用于调整图像的大小和定位,还用于其他效果,主要用于 t运行 调整坐标系起源。此外,该页面上的图像 不是 位图。因此,它没有简单的位置和大小...
各位程序员大家好。
我可以正确提取PDF文本坐标及其格式。但我不能用图像来做。我可以获得正确的宽度和高度,但它给了我错误的 x 和 y.
我正在使用 Photoshop 检查是否获得了正确的 x、y、width, height 坐标, 但只有 width 和 height 是正确的
这是我的代码:
@Override
public void processOperator(Operator operator, List<COSBase> arguments) throws IOException {
if ("cm".equals(operator.getName())) {
float width = ((COSNumber)arguments.get(0)).floatValue();
float height = ((COSNumber)arguments.get(3)).floatValue();
float x = ((COSNumber)arguments.get(4)).floatValue();
float y = ((COSNumber)arguments.get(5)).floatValue();
System.out.println("w: " + width + " h: " + height + " x: " + x + " y: " + y);
// process image coordinates
}
super.processOperator(operator, arguments);
}
这是我使用的示例 PDF:
http://persci.mit.edu/pub_pdfs/personal_photo_enhancement.pdf
我正在使用第 2 页。
这是程序的输出:
w: 503.87997 h: 152.64 x: 71.5168 y: 561.056
我使用 Photoshop 创建了一个矩形并叠加图像,但只有宽度和高度是正确的。
另一个问题
我使用了这个 PDF
http://www.ctex.org/documents/shredder/src/example.pdf
我用的是第17页
为什么PDF显示的坐标很多,而PDF中的图片只有一个?
w: 1.0 h: 1.0 x: 124.802 y: 776.998
w: 1.0 h: 1.0 x: 0.0 y: 3.587
w: 1.0 h: 1.0 x: 0.0 y: -3.985
w: 1.0 h: 1.0 x: 343.711 y: 0.398
w: 1.0 h: 1.0 x: -343.711 y: -24.906
w: 1.0 h: 1.0 x: 147.972 y: -106.0
w: 1.0 h: 1.0 x: 0.0 y: 0.0
w: 1.0 h: 1.0 x: 0.0 y: 0.0
w: 0.1 h: 0.1 x: 0.0 y: 0.0
w: 1.0 h: 1.0 x: 45.0 y: 0.0
w: 1.0 h: 1.0 x: -79.37 y: -21.918
w: 1.0 h: 1.0 x: 116.507 y: 0.0
w: 1.0 h: 1.0 x: -230.109 y: -2.145
w: 1.0 h: 1.0 x: 0.0 y: -20.324
w: 1.0 h: 1.0 x: 0.0 y: -13.682
w: 1.0 h: 1.0 x: 3.387 y: 2.989
w: 1.0 h: 1.0 x: 20.175 y: -2.989
w: 1.0 h: 1.0 x: -23.562 y: -0.398
w: 1.0 h: 1.0 x: 30.685 y: 3.387
w: 1.0 h: 1.0 x: 179.886 y: -66.21
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: -215.552 y: -17.195
w: 1.0 h: 1.0 x: 0.0 y: -13.682
w: 1.0 h: 1.0 x: 3.387 y: 2.989
w: 1.0 h: 1.0 x: 20.175 y: -2.989
w: 1.0 h: 1.0 x: -23.562 y: -0.398
w: 1.0 h: 1.0 x: 30.685 y: 3.387
w: 1.0 h: 1.0 x: -35.666 y: -76.173
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: -4.981 y: -41.843
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: -4.981 y: -51.806
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: 175.592 y: -19.925
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: -185.554 y: -19.925
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: 0.0 y: -37.121
w: 1.0 h: 1.0 x: 0.0 y: -13.682
w: 1.0 h: 1.0 x: 3.387 y: 2.989
w: 1.0 h: 1.0 x: 20.175 y: -2.989
w: 1.0 h: 1.0 x: -23.562 y: -0.398
w: 1.0 h: 1.0 x: 30.685 y: 3.387
w: 1.0 h: 1.0 x: 282.916 y: -18.389
w: 1.0 h: 1.0 x: 4.981 y: 0.0
w: 1.0 h: 1.0 x: -318.582 y: -17.196
w: 1.0 h: 1.0 x: 0.0 y: -13.682
w: 1.0 h: 1.0 x: 3.387 y: 2.989
w: 1.0 h: 1.0 x: 20.175 y: -2.989
w: 1.0 h: 1.0 x: -23.562 y: -0.398
w: 1.0 h: 1.0 x: 30.685 y: 3.387
w: 1.0 h: 1.0 x: 11.988 y: -11.216
w: 1.0 h: 1.0 x: 0.0 y: -14.833
w: 1.0 h: 1.0 x: 3.388 y: 4.926
w: 1.0 h: 1.0 x: 60.357 y: -4.926
w: 1.0 h: 1.0 x: -63.745 y: -0.399
w: 1.0 h: 1.0 x: 63.944 y: -3.985
w: 1.0 h: 1.0 x: -59.959 y: 0.0
w: 1.0 h: 1.0 x: 64.143 y: 0.0
w: 1.0 h: 1.0 x: -110.801 y: -13.101
w: 1.0 h: 1.0 x: 0.0 y: -2.241
w: 1.0 h: 1.0 x: 39.308 y: 2.241
w: 1.0 h: 1.0 x: 0.0 y: -2.241
w: 1.0 h: 1.0 x: -37.066 y: 0.0
w: 1.0 h: 1.0 x: 0.0 y: 13.294
w: 1.0 h: 1.0 x: 1.145 y: -9.907
w: 1.0 h: 1.0 x: 39.641 y: 11.302
w: 1.0 h: 1.0 x: 0.0 y: -15.686
w: 1.0 h: 1.0 x: 1.693 y: 14.291
w: 1.0 h: 1.0 x: 0.0 y: -12.896
w: 1.0 h: 1.0 x: 3.288 y: 2.989
w: 1.0 h: 1.0 x: 47.544 y: -2.989
w: 1.0 h: 1.0 x: -50.832 y: -0.299
w: 1.0 h: 1.0 x: 52.227 y: -1.096
w: 1.0 h: 1.0 x: -53.92 y: -0.597
w: 1.0 h: 1.0 x: 57.838 y: 14.888
w: 1.0 h: 1.0 x: 0.0 y: -11.22
w: 1.0 h: 1.0 x: 0.0 y: -2.473
w: 1.0 h: 1.0 x: 42.751 y: 2.473
w: 1.0 h: 1.0 x: 0.0 y: -2.473
w: 1.0 h: 1.0 x: -40.278 y: 0.0
w: 1.0 h: 1.0 x: 0.0 y: 13.693
w: 1.0 h: 1.0 x: 1.313 y: -9.907
w: 1.0 h: 1.0 x: -104.652 y: -78.762
w: 1.0 h: 1.0 x: 166.874 y: 0.0
w: 1.0 h: 1.0 x: 176.837 y: 0.0
问题的原因
您的代码不是真正寻找图像位置和大小,只是在友好的环境下它会找到它们。
您的代码只显示了一个没有明确上下文的方法(我想这就是为什么没有人认真分析该代码并发现问题的原因)。
考虑到上下文(PDFBox,内容流分析),我假设您创建了一个运算符处理器class,您在其中覆盖了processOperator
方法根据发布的代码。此外,我假设, 您使用某些 PDF 流引擎为 cm 指令注册了运算符处理器,并且 运行 针对您的样本 PDF .
鉴于这些假设,很清楚为什么您的运算符处理器的输出有时只包含图像大小和位置,但通常包含许多不相关的数据集:
指令cm的作用只是改变当前t运行sformation矩阵,与绘图没有直接或单一的关系位图图片!
赋予PDF规范:
Operands Operator Description
a b c d e f cm Modify the current transformation matrix (CTM) by concatenating the specified matrix (see 8.3.2, "Coordinate Spaces"). Although the operands specify a matrix, they shall be written as six separate numbers, not as an array.
(Table 57 – 图形状态运算符 – ISO 32000-1)
cm 参数偶尔包含图像大小和位置信息的唯一原因是位图绘制操作符将图像绘制到 1x1 区域(在用户 space unit) 其左下角为原点,并拉伸和移动坐标系,使该区域最终对应于结果页面上所需的图像大小,PDF 处理器修改当前的 t运行sformation 矩阵因此在绘制图像之前使用 cm 指令,通常就在之前。
如果他们在一个步骤中这样做(如上所述cm 将指定的矩阵连接到CTM,它会不替换它)并且不使用旋转或类似的细节,a和d(第一个和第四个cm参数)确实包含页面上图像的大小(默认用户space单位)和e和f(第五个和第六个cm参数)包含其左下角的坐标。
如何正确操作
因此,不仅要查看 cm 参数,还必须
- 解析有问题的内容流,
- 计算应用于 CTM 的所有矩阵的串联(同时跟踪中间 q 和 Q 指令的影响),和
- 当位图图像资源的Do指令发生时,检索当前t运行信息矩阵的值。
幸运的是,如果您愿意,PDFBox 已经为您完成了所有繁重的工作,请参见。 PrintImageLocations
个示例位于
- (对于 PDFBox 1.8.13)https://svn.apache.org/repos/asf/pdfbox/tags/1.8.13/examples/src/main/java/org/apache/pdfbox/examples/util/PrintImageLocations.java
- (对于 PDFBox 2.0.3)https://svn.apache.org/repos/asf/pdfbox/tags/2.0.3/examples/src/main/java/org/apache/pdfbox/examples/util/PrintImageLocations.java
关于您的问题
就 PDF 坐标系而言,您为 "personal_photo_enhancement.pdf" 第 2 页获得的坐标是正确的。可能是 Photoshop 使用了不同的坐标系,或者您检查了错误的图像角。
"example.pdf" 第 17 页的输出非常多,因为该 PDF 使用 CTM 操作,不仅用于调整图像的大小和定位,还用于其他效果,主要用于 t运行 调整坐标系起源。此外,该页面上的图像 不是 位图。因此,它没有简单的位置和大小...