如何在Python中仅读取图像的宽度和高度,而不读取数据?

11 浏览
0 Comments

如何在Python中仅读取图像的宽度和高度,而不读取数据?

我理解你可以使用PIL以如下方式获得图像尺寸:

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

然而,我希望能够在不加载图像到内存中的情况下获取图像的宽度和高度。这种可能吗?我只对图像的尺寸进行统计,不关心图像的内容。我只是想让处理过程更快。

0
0 Comments

如何在Python中仅读取图像的宽度和高度,而不读取数据?

问题的出现原因:

在处理图像时,有时只需要获取图像的宽度和高度,而不需要读取整个图像数据。然而,常用的图像处理库(如PIL)通常会读取整个图像数据,这在处理大型图像时可能会导致性能问题。因此,需要一种方法来仅读取图像的宽度和高度,而不读取整个图像数据。

解决方法:

可以使用一个名为"imagesize"的Python包来解决这个问题。该包可以在PyPI上找到,并且可以通过pip安装。使用该包的get函数可以轻松地获取图像的宽度和高度。

以下是使用"imagesize"包的示例代码:

import imagesize
width, height = imagesize.get("test.png")
print(width, height)

这将打印出图像的宽度和高度。

"imagesize"包非常高效,可以快速地获取图像的尺寸。根据进行的比较测试,它的速度要快于其他常用的图像处理库,如PIL和magic。

然而,需要注意的是,"imagesize"包不会考虑图像的EXIF旋转信息。如果图像使用EXIF头信息进行了旋转,那么图像的宽度和高度可能会被交换。目前,有一个关于这个问题的功能请求,但作者尚未给出答复。

通过使用"imagesize"包,我们可以轻松地获取图像的宽度和高度,而无需读取整个图像数据。这对于处理大型图像或只关心图像尺寸的情况非常有用。该包的使用非常简单,可以通过pip进行安装,并且具有良好的性能。然而,需要注意的是,它不会考虑图像的EXIF旋转信息。

0
0 Comments

问题的出现原因是PIL在调用.open方法时并没有将整个图像加载到内存中。根据PIL 1.1.7的文档,.open方法的文档字符串中写道:“打开一个图像文件,但不加载光栅数据”。实际上,.open方法只是返回一个文件对象和文件名。此外,文档还指出:“打开(file,mode=”r“)是一个惰性操作;该函数识别文件,但实际的图像数据直到尝试处理数据(或调用load方法)时才从文件中读取”。

解决方法是查看.open方法调用了_overload,这是一个特定于图像格式的重载方法。可以在新文件中找到每个_overload的实现,例如.jpeg文件在JpegImagePlugin.py中。在这个文件中有一个无限循环,当找到jpeg标记时会跳出循环。在循环中,通过调用handler方法设置了self.size,这是图像的尺寸。

但是,open方法是否获取了图像的尺寸,或者这也是一个惰性操作?如果是惰性操作,它是否同时读取图像数据?

Pillow是PIL的一个分支,但我在网上找不到官方文档链接。如果有人将其作为评论发表,我会更新答案。这段引用可以在文件Docs/PIL.Image.html中找到。

为了确保100%的准确性,我们需要深入研究每个特定于图像的实现。.jpeg格式看起来还不错,只要找到了头部。

对于晚来10年的人来说,这个答案对于jpg和png格式都是正确的,比cv2.imread要快得多。

问题的出现原因是PIL的.open方法并不会读取整个图像文件,而只是识别文件。解决方法是通过查看特定于图像格式的实现来获取图像的尺寸。

0
0 Comments

如何在Python中仅读取图像的宽度和高度,而不读取数据?

有时候我们只需要获取图像的宽度和高度,而不需要读取整个图像的内容。在这种情况下,使用Python Imaging Library(PIL)可能会显得过于复杂。下面我们将介绍一个解决方法。

解决方法:

一种解决方法是使用python magic模块来解析图像文件的输出。这个模块是对libmagic的封装,它通过读取尽可能少的字节来确定文件类型。

具体操作如下:

import magic
import re
t = magic.from_file('teste.png')
print(t)
print(re.search('(\d+) x (\d+)', t).groups())

上述代码将输出图像的宽度和高度。

如果上述方法对于JPEG文件无效,我们可以尝试读取更多的字节来获取图像的尺寸。下面是一个使用Python的核心模块编写的示例代码,它可以获取图像文件的宽度和高度,而无需任何第三方模块。

import os
import struct
class UnknownImageFormat(Exception):
    pass
def get_image_size(file_path):
    size = os.path.getsize(file_path)
    with open(file_path) as input:
        height = -1
        width = -1
        data = input.read(25)
        if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
            w, h = struct.unpack("= 24) and data.startswith('\211PNG\r\n\032\n')
              and (data[12:16] == 'IHDR')):
            w, h = struct.unpack(">LL", data[16:24])
            width = int(w)
            height = int(h)
        elif (size >= 16) and data.startswith('\211PNG\r\n\032\n'):
            w, h = struct.unpack(">LL", data[8:16])
            width = int(w)
            height = int(h)
        elif (size >= 2) and data.startswith('\377\330'):
            msg = " raised while trying to decode as JPEG."
            input.seek(0)
            input.read(2)
            b = input.read(1)
            try:
                while (b and ord(b) != 0xDA):
                    while (ord(b) != 0xFF): b = input.read(1)
                    while (ord(b) == 0xFF): b = input.read(1)
                    if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
                        input.read(3)
                        h, w = struct.unpack(">HH", input.read(4))
                        break
                    else:
                        input.read(int(struct.unpack(">H", input.read(2))[0])-2)
                    b = input.read(1)
                width = int(w)
                height = int(h)
            except struct.error:
                raise UnknownImageFormat("StructError" + msg)
            except ValueError:
                raise UnknownImageFormat("ValueError" + msg)
            except Exception as e:
                raise UnknownImageFormat(e.__class__.__name__ + msg)
        else:
            raise UnknownImageFormat(
                "Sorry, don't know how to get information from this file."
            )
    return width, height

上述代码将返回图像的宽度和高度。

这个解决方法没有使用PIL,因此不需要安装任何额外的依赖库。它适用于大多数环境,并且比PIL更加轻量级。

希望这个解决方法对你有帮助!如果你有其他更好的解决方法,欢迎分享。

0