我想使用pypdf迭代pdf页面中的所有对象。
我还想检查对象的类型是什么,无论是文本还是图形。
代码段将是一个很好的帮助。
非常感谢
答案 0 :(得分:5)
我认为PyPDF不适合这项工作。你需要的是解析页面本身(对于PyPDF有限的支持,请参阅the API documentation),然后能够将结果保存到另一个更改某些对象后的PDF对象。
您可以使用pdftk
解压缩PDF,这样您就可以使用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
这可能会写“ Se qu ence ”。它实际上由七个文本子对象组成,并且没有我知道的库可以将流“解密”到其组件子对象中,更不用说为它们分配适当的属性(在PDF中从图形状态下降,而在任何层次结构中)诸如XML之类的结构可能与单个节点相关联,可能通过继承)。
更多:流可能包含非文本命令(例如行)。然后更改“文本”描边颜色实际上也会改变非文本对象的颜色。
库应该为您提供类似于直接读取文本流所获得的详细访问级别;所以通过图书馆这样做似乎不太可能。
由于这是文字处理工作,您可以考虑将PDF转换为OpenOffice(使用 PDF导入扩展名),通过{{3}进行操作的可能性然后,从OpenOffice本身将其导出回PDF。
但要注意OOo python:文档很粗略,界面有时不稳定。访问“文本”可能不实用(更重要的是,因为文本只能逐行使用)。
另一种可能性(再次,不是对于胆小的人)是自己解码PDF。首先通过pdftk
以未压缩格式获取它。这将产生一个标题,后跟一个
INDEX R obj
<<
COMMANDS OR DATA
>>
[ stream
STREAM OF TEXT
endstream ]
endobj
您可以阅读流和每个对象:
/Length
长度,则可能是文本流。其他GOTO 3。/Length
。在对象的末尾,您将找到一个XREF对象,其中每个对象都以其所在的文件偏移量表示。这些偏移量(10位数字)必须根据您在XREF中保存的新偏移量进行重写。 此对象的开头应进入PDF文件末尾的 startxref 。
(要进行调试,首先要编写一个复制所有对象而不进行修改的例程。它必须重新计算外部参照和偏移量,并且仍然会产生与原始对象相同的PDF对象。)
这样获得的PDF可以由pdftk
重新压缩以节省空间。
关于PDF文本对象解析,你基本上逐行检查文本输出命令(参见there be dragons 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稍慢(但不是很多。你甚至可能都没注意到。)
答案 1 :(得分:0)
PDF structure非常复杂。另一种方法是导出文本,而不是只解析文本。
在每个页面上迭代并在其上使用extractText