Python 2.7 从大型PDF中提取页面大小

Python 2.7 从大型PDF中提取页面大小,python-2.7,pdf,Python 2.7,Pdf,我需要使用Python从PDF文件中提取以px/mm/cm/some为单位的页面数量和大小(遗憾的是,2.7,因为它是一个遗留项目)。问题是,这些文件可能非常庞大(数百个MIB),因为它们将包含大型图像 我不关心这个内容,我真的只想从文件的页面大小列表,尽可能少的RAM消耗 我发现有相当多的库可以做到这一点(包括但不限于答案中的库),但没有一个库提供关于内存使用的任何说明,而且我怀疑它们中的大多数(如果不是全部的话)在使用任何文件之前先在内存中读取整个文件,这不符合我的目的 是否有任何库只提取结

我需要使用Python从PDF文件中提取以px/mm/cm/some为单位的页面数量和大小(遗憾的是,2.7,因为它是一个遗留项目)。问题是,这些文件可能非常庞大(数百个MIB),因为它们将包含大型图像

我不关心这个内容,我真的只想从文件的页面大小列表,尽可能少的RAM消耗

我发现有相当多的库可以做到这一点(包括但不限于答案中的库),但没有一个库提供关于内存使用的任何说明,而且我怀疑它们中的大多数(如果不是全部的话)在使用任何文件之前先在内存中读取整个文件,这不符合我的目的

是否有任何库只提取结构并在不阻塞RAM的情况下为我提供所需数据?

受的启发,我发现那里建议的
libvips
,使用
poppler
(如果找不到
poppler
,它可以返回到其他库)

因此,我没有使用Superpower,它似乎适合多种类型的文档,而是使用了具有多个Python库的
poppler
。我选择并想出了这个解决方案:

from sys import argv

from pdflib import Document


doc = Document(argv[1])
for num, page in enumerate(doc, start=1):
    print(num, tuple(2.54 * x / 72 for x in page.size))
2.54*x/72
部件从
px
转换为
cm
,仅此而已

对264MiB文件进行速度和内存测试,每页有一个巨大的图像:

$ /usr/bin/time -f %M\ %e python t2.py big.pdf 
1 (27.99926666666667, 20.997333333333337)
2 (27.99926666666667, 20.997333333333337)
...
56 (27.99926666666667, 20.997333333333337)
21856 0.09
仅供参考,如果有人在寻找纯Python解决方案,我制作了一个粗糙的解决方案。未经彻底测试,且速度远慢于此(上述测试约30秒)。

可以做到这一点。当您打开PDF时,它会加载文件结构,并且仅当您请求像素时才会呈现每个页面

例如:

#!/usr/bin/python

import sys
import pyvips

i = 0
while True:
    try:
        x = pyvips.Image.new_from_file(sys.argv[1], dpi=300, page=i)
        print("page =", i)
        print("width =", x.width)
        print("height =", x.height)
    except:
        break

    i += 1
libvips 8.7将于下周左右发布,它添加了一个名为
n-pages
的新元数据项,您可以使用它来获取文档的长度。在发布之前,您只需不断增加页码,直到出现错误

使用,当我运行程序时,我看到:

$ /usr/bin/time -f %M:%e ./sizes.py ~/pics/r8.pdf 
page = 0
width = 2480
height = 2480
page = 1
width = 2480
height = 2480
page = 2
width = 4960
height = 4960
...
page = 49
width = 2480
height = 2480
55400:0.19
因此,它以0.2秒的实时速度打开了50页,总峰值内存使用量为55mb。py3就是这样,但py2也可以。尺寸以300 DPI的像素为单位


如果将
page
设置为-1,它将以单个非常高的图像加载文档中的所有页面。遗憾的是,所有页面的大小都必须相同。

这是一个非常好的解决方案,正如广告所宣传的那样,但我在安装
libvips
时遇到了问题,因为它无法识别PDF。这让我找到了一个更简单的解决方案,我将在下面使用并发布。非常感谢。这有点取决于您的平台——不是每个人都使用poppler支持进行编译,因为它是GPL。libvips也可以使用PDFium,但这很难构建。很高兴你解决了你的问题。我们看看能不能让它在Heroku上运行。那我的问题就解决了。这就是为什么我只选择了
poppler
。但即使失败了,我也会有更多的libs来尝试。我真的很感谢你的帮助。而
/usr/bin/time
部分对我来说也是新的。我只知道内置的一个。遗憾的是,这一个是隐藏的。