【问题标题】:Extracting page sizes from PDF in Python在 Python 中从 PDF 中提取页面大小
【发布时间】:2011-09-08 00:20:43
【问题描述】:

我想阅读 PDF 并获取其页面列表和每页的大小。我不需要以任何方式操纵它,只需阅读即可。

目前正在试用 pyPdf,它可以满足我的所有需求,除了获取页面大小的方法。了解我可能不得不遍历,因为 pdf 文档中的页面大小可能会有所不同。我可以使用其他库/方法吗?

我尝试使用 PIL,一些在线食谱甚至使用 d=Image(imagefilename),但它从不读取我的任何 PDF - 它读取我扔给它的所有其他内容 - 甚至一些我不知道 PIL 可以做的事情.

感谢任何指导 - 我在 windows 7 64, python25 上(因为我也做 GAE 的东西),但我很高兴在 Linux 或更现代的 pythiis 上做。

【问题讨论】:

  • PIL 不(而且很可能永远不会)支持 PDF,因为它们是一种非常复杂的矢量图形。 PIL 专注于光栅图像。使用 PDF 是专用库的任务,例如 pikepdf 或 pymupdf。

标签: python pdf


【解决方案1】:

这可以通过PyPDF2来完成:

>>> from PyPDF2 import PdfFileReader
>>> input1 = PdfFileReader(open('example.pdf', 'rb'))
>>> input1.getPage(0).mediaBox
RectangleObject([0, 0, 612, 792])

(以前称为pyPdf,现在仍参考其文档。)

【讨论】:

  • input1 = PdfFileReader(file('example.pdf', 'rb') 这样对我有用。
  • 对我不起作用;我得到 TypeError: 'str' object is not callable as an error.
  • 从 pyPdf 导入 PdfFileReader
  • [0, 0, 宽度, 高度]
  • @Astrophe 是正确的,但有一个更易读(但未记录)的解决方案。如果你看一下the sources,你会发现RectangleObject 类有几个方便的方法,包括getWidth()(和getHeight()),这比@987654328 好很多 @
【解决方案2】:

pdfrw:

>>> from pdfrw import PdfReader
>>> pdf = PdfReader('example.pdf')
>>> pdf.pages[0].MediaBox
['0', '0', '595.2756', '841.8898']

长度以磅为单位(1 pt = 1/72 英寸)。格式为[x0, y0, x1, y1](谢谢,mara004!)。

【讨论】:

  • “长度以磅为单位” 除非页面包含可用于在此处更改单位的 UserUnit 条目。诚然,这个选项很少使用。
  • 我试过这个,但它有时无法提取信息,而 PyMuPDF(cges30901 的答案)一直表现良好。原因是 pdfrw 有时无法从 pdf 文件中提取“/MediaBox”键(奇怪)。
  • "格式为 ['0', '0', width, height]" - 这是错误的。格式为 [x0, y0, x1, y1]。不一定要以0开头。
【解决方案3】:

2021-07-22 更新:原来的答案并不总是正确的,所以我更新了我的答案。

PyMuPDF:

>>> import fitz
>>> doc = fitz.open("example.pdf")
>>> page = doc[0]
>>> print(page.rect.width, page.rect.height)
842.0 595.0
>>> print(page.mediabox.width, page.mediabox.height)
595.0 842.0

mediaboxrect 的返回值属于Rect 类型,具有“宽度”和“高度”属性。 mediabox 和 rect 之间的一个区别是 mediabox 与文档中的 /MediaBox 相同,并且在页面旋转时不会改变。但是,rect 会受到旋转的影响。有关 PyMuPDF 中不同框的更多信息,您可以阅读glossary

【讨论】:

  • 你也可以简单地写doc[0]而不是doc.loadPage(0) :-)
  • page 这里还有一个属性MediaBoxSize,它返回大小。
  • 这是读取 PDF 文件最快的包装库
  • Page 对象的CropBox 属性将未旋转 大小作为Rect 对象返回。 Rect 具有 widthheight 属性。这是获取相关位的快速方法。
  • @rain01 顺序没有变化,但是当页面旋转90度或270度时,一列的像素数实际上是真正的宽度,一行的像素数是真正的宽度高度。
【解决方案4】:

对于 pdfminer python 3.x (pdfminer.six)(没有在 python 2.7 上尝试):

parser = PDFParser(open(pdfPath, 'rb'))
doc = PDFDocument(parser)
pageSizesList = []
for page in PDFPage.create_pages(doc):
    print(page.mediabox) # <- the media box that is the page size as list of 4 integers x0 y0 x1 y1
    pageSizesList.append(page.mediabox) # <- appending sizes to this list. eventually the pageSizesList will contain list of list corresponding to sizes of each page

【讨论】:

  • 也适合我。你也知道mediaboxcropbox的区别吗?
  • 简而言之,mediabox 是整个页面的大小,包括白边。 cropbox 是页面大小 + 应用程序用来执行任何功能的任何区域。结帐wiki.scribus.net/canvas/…
  • 如果定义了裁剪框,它就是 PDF 查看器通常会显示的页面部分。
【解决方案5】:

使用 pikepdf:

import pikepdf

# open the file and select the first page
pdf = pikepdf.Pdf.open("/path/to/file.pdf")
page = pdf.pages[0]

if '/CropBox' in page:
    # use CropBox if defined since that's what the PDF viewer would usually display
    relevant_box = page.CropBox
elif '/MediaBox' in page:
    relevant_box = page.MediaBox
else:
    # fall back to ANSI A (US Letter) if neither CropBox nor MediaBox are defined
    # unlikely, but possible
    relevant_box = [0, 0, 612, 792]

# actually there could also be a viewer preference ViewArea or ViewClip in
# pdf.Root.ViewerPreferences defining which box to use, but most PDF readers 
# disregard this option anyway

# check whether the page defines a UserUnit
userunit = 1
if '/UserUnit' in page:
    userunit = float(page.UserUnit)

# convert the box coordinates to float and multiply with the UserUnit
relevant_box = [float(x)*userunit for x in relevant_box]

# obtain the dimensions of the box
width  = abs(relevant_box[2] - relevant_box[0])
height = abs(relevant_box[3] - relevant_box[1])

rotation = 0
if '/Rotate' in page:
    rotation = page.Rotate

# if the page is rotated clockwise or counter-clockwise, swap width and height
# (pdf rotation modifies the coordinate system, so the box always refers to 
# the non-rotated page)
if (rotation // 90) % 2 != 0:
    width, height = height, width

# now you have width and height in points
# 1 point is equivalent to 1/72in (1in -> 2.54cm)

【讨论】:

    【解决方案6】:

    另一种方法是使用popplerqt4

    doc = popplerqt4.Poppler.Document.load('/path/to/my.pdf')
    qsizedoc = doc.page(0).pageSize()
    h = qsizedoc.height() # given in pt,  1pt = 1/72 in
    w = qsizedoc.width() 
    

    【讨论】:

    猜你喜欢
    • 2019-01-02
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 2011-05-23
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    相关资源
    最近更新 更多