【问题标题】:pyPdf IndirectObject in /Rotate/Rotate 中的 pyPdf IndirectObject
【发布时间】:2013-12-17 22:57:07
【问题描述】:

我们有一个简单的脚本来读取传入的 PDF 文件。如果是横向,它会将其旋转到纵向以供其他程序稍后使用。 pyPdf 一切运行良好,直到我遇到一个文件,其中 IndirectObject 作为页面上 /Rotate 键的值。该对象是可解析的,因此我可以知道 /Rotate 值是什么,但是当尝试旋转顺时针或旋转计数器顺时针时,我得到了回溯,因为 pyPdf 不期望 /Rotate 中有 IndirectObject。我已经做了很多尝试用值覆盖 IndirectObject 的文件,但我没有得到任何结果。我什至尝试将相同的 IndirectObject 传递给 rotateClockwise 并抛出相同的回溯,即 pdf.pyc 中前面的一行

我的问题简单地说是。 . .是否有 pyPdf 或 PyPDF2 的补丁使其不会因这种设置而窒息,或者我可以用不同的方式来旋转页面,或者我还没有看到/考虑过的不同的库?我试过 PyPDF2 也有同样的问题。我将 PDFMiner 视为替代品,但它似乎更倾向于从 PDF 文件中获取信息而不是操纵它们。这是我在 ipython 中使用 pyPDF 播放文件的输出,PyPDF2 的输出非常相似,但信息的某些格式略有不同:

In [1]: from pyPdf import PdfFileReader

In [2]: mypdf = PdfFileReader(open("RP121613.pdf","rb"))

In [3]: mypdf.getNumPages()
Out[3]: 1

In [4]: mypdf.resolvedObjects
Out[4]: 
{0: {1: {'/Pages': IndirectObject(2, 0), '/Type': '/Catalog'},
     2: {'/Count': 1, '/Kids': [IndirectObject(4, 0)], '/Type': '/Pages'},
     4: {'/Count': 1,
     '/Kids': [IndirectObject(5, 0)],
     '/Parent': IndirectObject(2, 0),
     '/Type': '/Pages'},
     5: {'/Contents': IndirectObject(6, 0),
     '/MediaBox': [0, 0, 612, 792],
     '/Parent': IndirectObject(4, 0),
     '/Resources': IndirectObject(7, 0),
     '/Rotate': IndirectObject(8, 0),
     '/Type': '/Page'}}}

In [5]: mypage = mypdf.getPage(0)

In [6]: myrotation = mypage.get("/Rotate")

In [7]: myrotation
Out[7]: IndirectObject(8, 0)

In [8]: mypdf.getObject(myrotation)
Out[8]: 0

In [9]: mypage.rotateCounterClockwise(90)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/root/<ipython console> in <module>()

/usr/lib/python2.7/site-packages/pyPdf/pdf.pyc in rotateCounterClockwise(self, angle)
   1049     def rotateCounterClockwise(self, angle):
   1050         assert angle % 90 == 0
-> 1051         self._rotate(-angle)
   1052         return self
   1053 

/usr/lib/python2.7/site-packages/pyPdf/pdf.pyc in _rotate(self, angle)
   1054     def _rotate(self, angle):
   1055         currentAngle = self.get("/Rotate", 0)
-> 1056         self[NameObject("/Rotate")] = NumberObject(currentAngle + angle)
   1057 
   1058     def _mergeResources(res1, res2, resource):

TypeError: unsupported operand type(s) for +: 'IndirectObject' and 'int'

In [10]: mypage.rotateClockwise(90)       
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/root/<ipython console> in <module>()

/usr/lib/python2.7/site-packages/pyPdf/pdf.pyc in rotateClockwise(self, angle)
   1039     def rotateClockwise(self, angle):
   1040         assert angle % 90 == 0
-> 1041         self._rotate(angle)
   1042         return self
   1043 

/usr/lib/python2.7/site-packages/pyPdf/pdf.pyc in _rotate(self, angle)
   1054     def _rotate(self, angle):
   1055         currentAngle = self.get("/Rotate", 0)
-> 1056         self[NameObject("/Rotate")] = NumberObject(currentAngle + angle)
   1057 
   1058     def _mergeResources(res1, res2, resource):

TypeError: unsupported operand type(s) for +: 'IndirectObject' and 'int'

In [11]: mypage.rotateCounterClockwise(myrotation)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/root/<ipython console> in <module>()

/usr/lib/python2.7/site-packages/pyPdf/pdf.pyc in rotateCounterClockwise(self, angle)
   1048     # @param angle Angle to rotate the page.  Must be an increment of 90 deg.

   1049     def rotateCounterClockwise(self, angle):
-> 1050         assert angle % 90 == 0
   1051         self._rotate(-angle)
   1052         return self

TypeError: unsupported operand type(s) for %: 'IndirectObject' and 'int'

如果有人想深入了解它,我很乐意提供我正在使用的文件。

【问题讨论】:

  • 是否可以旋转在 pdf 中找到的对象。例如,如果在 pdf 中找到的图像可以如果横向我们可以旋转到 potrait。一般来说,我们可以操作 pdf 中的对象并将其替换为新对象。如果是,那么任何人都可以分享一些有用的链接来参考

标签: python pdf rotation


【解决方案1】:

您需要将 getObject 应用于 IndirectObject 的实例,因此在您的情况下应该是

myrotation.getObject()

【讨论】:

  • 在偶然发现 '/Contents' 是 IndirectObject[] 的 PDF 后来到这里。这是正确的,调用 getObject 会返回实际的实例!
【解决方案2】:

我意识到这是一个老问题,但我在搜索中发现这篇文章试图比我找到解决方案更早解决。据我了解,这是一个错误。

https://github.com/mstamy2/PyPDF2/pull/338/files

总之,我直接编辑了 PyPDF2 源代码来实现修复。找到 PyPDF2/pdf.py 并搜索 def _rotate(self,angle):line。替换为以下内容:

def _rotate(self, angle):
    rotateObj = self.get("/Rotate", 0)
    currentAngle = rotateObj if isinstance(rotateObj, int) else rotateObj.getObject()
    self[NameObject("/Rotate")] = NumberObject(currentAngle + angle)

它现在就像一个魅力。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 2022-12-26
    • 1970-01-01
    • 2014-03-26
    • 2011-11-12
    • 2022-12-01
    • 1970-01-01
    相关资源
    最近更新 更多