当前位置: 首页 > 知识库问答 >
问题:

PDFBox:提取图像位置(错误的x和y)

那鹏
2023-03-14

再次向各位程序员问好。

我可以正确提取PDF文本坐标及其格式。但我不能用图像。我可以得到正确的宽度和高度,但它给了我错误的x和y。

我正在使用Photoshop检查我是否得到了正确的x,y,宽度,高度坐标,但只有宽度和高度是正确的

这是我的代码:

@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

我用的是第二页。

这是程序的输出:

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

共有1个答案

聂永怡
2023-03-14

您的代码并没有真正查找图像位置和大小,只是在友好的情况下找到它们。

您的代码只显示一个没有显式上下文的方法(我想这就是为什么没有人认真分析该代码并发现问题的原因)。

但是,考虑到上下文(PDFBox,内容流分析),我假设您创建了一个操作符处理器类,在该类中,您根据发布的代码重写了processOperator方法。此外,我假设您使用一些PDF流引擎注册了cm指令的操作员处理器,并针对示例PDF运行了该处理器。

考虑到这些假设,很清楚为什么操作员处理器的输出有时只包含图像大小和位置,但通常包含许多不相关的数据集:

指令cm的效果仅仅是改变当前的变换矩阵,它与绘制位图图像没有直接或单独的关系!

授予PDF规范:

操作数运算符说明

a b c d e f cm通过连接指定矩阵来修改当前变换矩阵(CTM)(参见8.3.2,“坐标空间”)。虽然操作数指定了一个矩阵,但它们应被写入六个独立的数字,而不是数组。

(表57–图形状态操作符–ISO 32000-1)

cm参数偶尔包含图像大小和位置信息的唯一原因是位图绘制操作符将图像绘制到1x1区域(以用户空间为单位),该区域的左下角是原点,并拉伸和移动坐标系,以便该区域最终与结果页上的所需图像大小相对应,PDF处理器在绘制图像之前(通常在绘制之前)使用cm指令相应地修改当前变换矩阵。

如果在一个步骤中这样做(如上所述,cm将指定的矩阵连接到CTM,但不会替换它),并且不使用旋转或类似的精度,则a和d(第一个和第四个cm参数)确实包含页面上图像的大小(默认用户空间单位),e和f(第五个和第六个cm参数)包含其左下角的坐标。

因此,与其只看cm参数,不如

  • 解析有问题的内容流,
  • 计算应用于CTM的所有矩阵的级联(同时跟踪中间q和Q指令的影响),并且
  • 当位图图像资源的Do指令出现时,检索当前转换矩阵的值。

幸运的是,如果您愿意,PDFBox已经为您完成了引擎盖下的所有繁重工作,请参见

  • (用于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操作不仅用于调整和定位图像,还用于其他效果,主要用于转换坐标系原点。此外,该页面上的图像不是位图。因此,它没有简单的位置和大小...

 类似资料:
  • 主要内容:从PDF文档生成图像在前一章中,我们已经看到了如何合并多个PDF文档。 在本章中,我们将了解如何从PDF文档的页面提取图像。 从PDF文档生成图像 PDFBox库提供了一个名称为的类,它将PDF文档呈现为AWT BufferedImage。 以下是从PDF文档生成图像的步骤。 第1步:加载现有的PDF文档 使用类的静态方法加载现有的PDF文档。 此方法接受一个文件对象作为参数,因为这是一个静态方法,可以使用类名称调用

  • 我正在尝试从pdf中提取图像。pdfbox能够从大多数PDF中提取图像,但它们是一些无法通过pdfbox提取图像的PDF。 为了提取图像,我使用以下代码:无法从PDFA1-a格式文档中提取图像 您可以从以下链接下载带有此问题的pdf示例:http://myslams.com/test/2.pdf 是他们的代码出错了,也许是我忘记处理了,还是他们的pdf一起出了问题?

  • 当我使用pdfbox提取图像时,我得到了一些PDF图像的不正确dpi。当我使用Photoshop或Acrobat Reader Pro提取图像时,我可以看到图像的dpi是200使用windows照片查看器,但当我使用pdfbox提取图像时,dpi是72。 为了提取图像,我使用以下代码:无法从PDFA1-a格式文档中提取图像 当我检查日志时,我看到一个不寻常的条目:2015-01-23-main——

  • 这是我的线程的最终输出,它获取屏幕截图并将其存储在一个矢量中。 用于获取屏幕截图,这些截图基本上是屏幕的光栅,不包含光标位置。作为一种解决办法,我使用类获取,然后获取一个。然后在该点绘制图像。 如果将记录区域设置为全屏分辨率,则一切都很酷。但是,如果我改变了记录区域,光标会被绘制在错误的位置。 这个黑色光标应该在Eclipse IDE的Play按钮的顶部。然而,它处于错误的位置。 如果光标超出记录

  • 我在iOS 7上运行良好的应用程序与iOS 8 SDK不兼容。 CLLocationManager不返回位置,并且我在

  • 我正在使用PDFBox从我的pdf(只包含JPG的)中提取图像。 因为我将把这些图像保存在我的数据库中,所以我想先把每个图像直接转换成一个inputstream对象,而不把文件临时放在我的文件系统上。然而,我在这方面遇到了困难。我认为这是因为使用了,就像我在下面的示例中所做的那样: 然而,这是可行的: 知道我如何将每个PDXObjectImage(或我能得到的任何其他对象)转换为InputStre