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

时间:2016-11-29 08:37:55

标签: java pdfbox

再次邀请其他程序员,

我可以正确提取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

我正在使用第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

1 个答案:

答案 0 :(得分:4)

问题的原因

您的代码不会 真正寻找图像位置和尺寸,只是在友情的情况下找到它们。

您的代码仅显示没有显式上下文的单个方法(我认为,这是没有人认真分析该代码并发现问题的原因)。

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

鉴于这些假设,很清楚为什么运算符处理器的输出有时只包含图像大小和位置,但通常包含许多不相关的数据集:

指令 cm 的效果仅仅是改变当前的变换矩阵,它与绘制位图图像不是立即或奇怪的相关!

授予PDF规范:

  

操作数   <强>操作   描述

     

a b c d e f   的厘米   通过连接指定的矩阵来修改当前的变换矩阵(CTM)(参见8.3.2,&#34;坐标空间&#34;)。尽管操作数指定了一个矩阵,但它们应该写成六个单独的数字,而不是数组。

(表57 - 图形状态运算符 - ISO 32000-1)

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

如果他们一步到位(如上面引用 cm 连接指定的矩阵到CTM,它不替换它)并且不使用轮换或类似的细节, a d (第一个和第四个 cm 参数)确实包含大小页面上的图像(默认用户空间单位)和 e f (第五个和第六个 cm 参数)包含坐标它的左下角。

如何正确执行

因此,不仅要查看 cm 参数,还必须

  • 解析有问题的内容流
  • 计算应用于CTM的所有矩阵的连接(也跟踪中间 q Q 指令的影响)和
  • 在发生位图图像资源的执行指令时检索当前变换矩阵的值。

幸运的是,如果你愿意的话,PDFBox已经为你做了所有繁重的工作,参见

中的PrintImageLocations示例

关于你的问题

你得到的坐标&#34; personal_photo_enhancement.pdf&#34;就PDF坐标系而言,第2页是正确的。可能Photoshop使用不同的坐标系,或者您检查了错误的图像角落。

你有很多输出&#34; example.pdf&#34;第17页因为PDF使用CTM操作不仅用于调整和定位图像,还用于其他效果,主要用于翻译坐标系原点。此外,该页面上的图像不是位图。因此,它没有简单的位置和大小...