5

我想使用 pypdf 遍历 pdf 页面中的所有对象。

我还想检查对象的类型是什么,是文本还是图形。

代码片段将是一个很大的帮助。

非常感谢

4

2 回答 2

5

我认为 PyPDF 不是这项工作的正确工具。您需要解析页面本身(PyPDF 对其支持有限,请参阅API 文档),然后在更改某些对象后能够将结果保存在另一个 PDF 对象中。

您可以使用 解压缩 PDF pdftk,这将允许您使用pdfrw

然而,从你写的,

我的最终目标是为每个文本对象着色不同。

“文本对象”可能是由(例如)不同段落中的不同行组成的相当复杂的对象。这可能是,并且您可能将其视为单个实体。在这个实体中可能已经有几个不同的文本颜色命令。

例如,您可能有一个带有此文本序列的流(这是用“内部”语言编写的):

12.84 0 Td(S)Tj
0.08736 Tc
9 0 Td(e)Tj
0.06816 Tc
0.5 g
7.55999 0 Td(qu)Tj
0.08736 Tc
1 g
16.5599 0 Td(e)Tj
0.06816 Tc
7.55999 0 Td(n)Tj
0.08736 Tc
8.27996 0 Td(c)Tj
-0.03264 Tc
0.13632 Tw
7.55999 0 Td(e )Tj
0.06816 Tc
0 Tw

这可能会写成“序列。它实际上由七个文本子对象组成,并且我所知道的没有库可以将流“解密”为其组件子对象,更不用说为它们分配适当的属性(在 PDF 中从图形状态下降,而在任何分层像 XML 这样的结构可能会与单个节点相关联,可能是通过继承)。

更多:流可能包括非文本命令(例如行)。然后改变“文本”的描边颜色实际上也会改变非文本对象的颜色

库应该为您提供与直接读取文本流类似的详细访问级别;所以通过图书馆这样做似乎不太可能。

由于这是文字处理工作,您可能会考虑将 PDF 转换为 OpenOffice(使用PDF 导入扩展),通过OOo python对其进行操作,然后从 OpenOffice 本身将其导出回 PDF。

但是要小心,因为有龙:文档很粗略,界面有时不稳定。访问“文本”可能不切实际(更是如此,因为您只能逐行使用文本)。

另一种可能性(同样,不是胆小的人)是自己解码 PDF。首先通过pdftk. 这将产生一个标题,后跟表单中的对象流

INDEX R obj
<<
COMMANDS OR DATA
>>
[ stream 
STREAM OF TEXT
endstream ]
endobj

您可以读取流,并且对于每个对象:

  1. 如果 COMMANDS OR DATA 只是/Length 长度,它可能是一个文本流。否则转到 3。
  2. 解析对象(见下文)。如果长度发生变化,请记住/Length适当更新。
  3. 记下当前输出文件的偏移量,将其保存在 XREF[i](“第 i 个对象的参考偏移量”)中,并将其保存到输出文件中。

在对象的末尾,您会找到一个 XREF 对象,其中每个对象都用它所在的文件偏移量表示。这些偏移量(10 位数字)必须根据您保存在 XREF 中的新偏移量进行重写。对象的开头应进入PDF 文件末尾的startxref 。

(要调试,首先编写一个复制所有对象而不进行修改的例程。它必须重新计算外部参照和偏移量,并且仍然产生与原始对象相同的 PDF 对象)。

这样获得的PDF可以重新压缩pdftk以节省空间。

关于 PDF 文本对象解析,您基本上可以逐行检查以查找文本输出命令(参见PDF 参考5.3.2)。您将看到的大多数命令将是Tj

9.95999 0 Td(Hello, world)Tj

和颜色更改命令(参见#4.5.1;最常用的是 g 和 rg。)

1 g             # Sets color to black (1 in colorspace Gray)
1 0 0 rg        # Sets color to red (1,0,0 in colorspace RGB)

然后,您将跟踪我们使用的任何颜色,例如,可以在您选择Tj的几个命令之间包含每个命令RG- 一个设置文本颜色,一个恢复原始颜色。这样,您将确保图形状态不会“溢出”到任何附近的对象、线条等;它会增加对象Length并使生成的 PDF 变慢一点(但不是很慢。你甚至可能没有注意到)。

于 2012-10-20T15:47:21.750 回答
0

PDF结构非常复杂。如果您只想要文本,另一种方法是导出文本而不是解析它。

在每个页面上迭代并在其上使用extractText

于 2012-10-20T08:19:29.523 回答