小编典典

获取图像大小而无需将图像加载到内存中

python

我了解您可以通过以下方式使用PIL获得图像尺寸

from PIL import Image
im = Image.open(image_filename)
width, height = im.size

但是,我想获取图像的宽度和高度, 而不 必将图像加载到内存中。那可能吗?我只是在统计图像大小,并不关心图像内容。我只是想加快处理速度。


阅读 164

收藏
2021-01-20

共1个答案

小编典典

正如注释所暗示的那样,PIL在调用时不会将图像加载到内存中.open。查看的文档PIL 1.1.7,文档字符串.open说:

def open(fp, mode="r"):
    "Open an image file, without loading the raster data"

源代码中有一些文件操作,例如:

 ...
 prefix = fp.read(16)
 ...
 fp.seek(0)
 ...

但是这些几乎不构成读取整个文件。实际上,.open仅在成功时返回文件对象和文件名。另外文档说:

打开(文件,模式=“ r”)

打开并标识给定的图像文件。

这是一个懒惰的操作;此功能可识别文件,但在尝试处理数据(或调用 load 方法)之前,不会从文件中读取实际图像数据。

深入研究,我们看到.open调用_open是特定于图像格式的重载。每个实现_open都可以在新文件中找到,例如。.jpeg文件位于中JpegImagePlugin.py。让我们深入研究一下。

这里的事情似乎有些棘手,其中有一个无限循环,当找到jpeg标记时,该循环就会中断:

    while True:

        s = s + self.fp.read(1)
        i = i16(s)

        if i in MARKER:
            name, description, handler = MARKER[i]
            # print hex(i), name, description
            if handler is not None:
                handler(self, i)
            if i == 0xFFDA: # start of scan
                rawmode = self.mode
                if self.mode == "CMYK":
                    rawmode = "CMYK;I" # assume adobe conventions
                self.tile = [("jpeg", (0,0) + self.size, 0, (rawmode, ""))]
                # self.__offset = self.fp.tell()
                break
            s = self.fp.read(1)
        elif i == 0 or i == 65535:
            # padded marker or junk; move on
            s = "\xff"
        else:
            raise SyntaxError("no marker found")

看起来如果文件格式错误,它 可以 读取整个文件。但是,如果读取信息标记“
OK”,则应尽早爆发。该功能handler最终设置self.size图像的尺寸。

2021-01-20