将高亮/注释映射到pdf

时间:2017-07-04 04:58:17

标签: parsing pdf pdf-generation

所以我有这个样本的pdf文件,在不同的行上有三个单词:

"
hello
there
world
"

我突出显示了" 那里"在第二行。在内部,在pdf中,我试图将高亮/注释结构映射到文本(BT)区域。

对应于单词" 那里"看起来像这样:

BT
/F0 14.6599998 Tf
1 0 0 -1 0 130 Tm
96 0 Td <0057> Tj
4.0719757 0 Td <004B> Tj
8.1511078 0 Td <0048> Tj
8.1511078 0 Td <0055> Tj
4.8806458 0 Td <0048> Tj
ET

我还有一个注释部分,其中我的突出显示具有以下rect尺寸:

18 0 19 15 20 694 21 786 22 853 23 1058 24 1331 [19 0 R 20 0 R]<</AP<</N 10 0 R>>
...
(I left the top part of the annotation out on purpose because it is long.  I extracted what i thought were the most important parts.
Rect[68.0024 690.459 101.054 706.37]

我对我的文字如何映射到我所拥有的这一个亮点感到困惑。坐标似乎不匹配(130 y vs 690 y)?我正在寻找合适的位置并正确解释我的文本和/或突出显示注释坐标吗?

更新

我想添加更多有关我如何创建此测试pdf的信息。

重新创建pdf非常简单。我去谷歌文档并创建了一个空文档。我在三行上写了如上所述的文字。我将其作为pdf下载,然后在adobe acrobat reader DC(我认为是最新版本)中打开它。然后我使用adobe acrobat reader突出显示指定的行并重新保存。之后我使用了一些python来解压缩pdf部分。 解压缩pdf部分的python代码:

import re
import zlib

pdf = open("helloworld.pdf", "rb").read()
stream = re.compile(r'.*?FlateDecode.*?stream(.*?)endstream', re.S)

for s in stream.findall(pdf):
    s = s.strip('\r\n')
    try:
        print(zlib.decompress(s))
        print("")
    except:
        pass

1 个答案:

答案 0 :(得分:1)

不幸的是,OP只解释了他是如何创建自己的文档而不是自己共享文档的。我按照他的指示,但注释的坐标不同。虽然我只有这份文件可供解释,但OP必须在心理上将以下内容改编成他文件中的准确数字。

起始坐标系

裁剪框隐含文档中的起始(默认)用户坐标系。在手头的文件中,裁剪框被定义为

/CropBox [0 0 596 843]

即。可见页面宽596单位,高843单位(默认用户单位为1/72“这是A4格式),原点位于左下角。 x 坐标增加到对, y 坐标向上增加。因此,坐标系通常也以数学开始。

注释矩形

这也是注释矩形坐标的坐标系。

在手头的情况下,他们是

/Rect [68.0595 741.373 101.138 757.298]

即。左下角的矩形位于(68.0595,741.373),右上角位于(101.138,757.298)。

坐标系的转换

在页面内容流中,直到OP已经识别的文本对象,坐标系变换了很多次。

镜像,翻译

在页面内容的第一行

1 0 0 -1 0 843 cm

此变换将原点向上移动843个单位并镜像(乘以 -1 )y坐标。

因此,现在有一个坐标系,其左上角的原点和 y 坐标向下增加。

缩放

稍后在内容流中缩放坐标系

.75062972 0 0 .75062972 0 0 cm

因此,坐标单位被压缩到其原始宽度和高度的约3/4,即沿 x y 的每个单位仅为1/96“宽/高。

文字“那里”

只有在将这些变换应用于坐标系之后,才会绘制由OP标识的文本对象。首先是设置和更改文本矩阵:

1 0 0 -1 0 130 Tm

这会将文本矩阵设置为在 y 方向上翻译130个单位并再次镜像 y 坐标。 (再次镜像是必要的,否则文本将被颠倒。)

96 0 Td

这会通过沿 x 轴移动96个单位来更改文本矩阵。

绘制文本的起点是坐标系的原点,首先通过镜像和平移改变,然后通过缩放当前的变换矩阵,然后根据文本矩阵进行镜像和平移。

匹配吗?

此点在默认用户坐标系中的坐标是什么?

x = (0 + 96) * .75062972 = 72 (approximately)
y = (((0 * (-1)) + 130) * .75062972) * (-1) + 843 = 745,4 (approximately)

这与注释矩形(见上文)匹配, x 坐标介于68.0595和101.138之间, y 坐标介于741.373和757.298之间。

所以

  

我对我的文本如何映射到我拥有的这一个亮点感到困惑。坐标似乎不匹配(130 y vs 690 y)?我正在寻找合适的位置并正确解释我的文本和/或突出显示注释坐标吗?

坐标执行匹配,您只需要确保应用当前变换矩阵和文本矩阵的变换。