如何使用标准Python类获取图像大小(不使用外部库)?

87 投票
10 回答
130151 浏览
提问于 2025-04-17 05:46

我正在使用Python 2.5。想用Python自带的标准类来确定一个文件的图片大小。

我听说过PIL(Python图像库),但它需要安装才能使用。

我想知道有没有办法仅用Python 2.5自带的模块来获取图片的大小,而不使用任何外部库。

需要注意的是,我想支持常见的图片格式,特别是JPG和PNG。

10 个回答

20

这里有一种方法,可以在不使用第三方模块的情况下获取PNG文件的尺寸。这个方法来自于 Python - 验证PNG文件并获取图像尺寸

import struct

def get_image_info(data):
    if is_png(data):
        w, h = struct.unpack('>LL', data[16:24])
        width = int(w)
        height = int(h)
    else:
        raise Exception('not a png image')
    return width, height

def is_png(data):
    return (data[:8] == '\211PNG\r\n\032\n'and (data[12:16] == 'IHDR'))

if __name__ == '__main__':
    with open('foo.png', 'rb') as f:
        data = f.read()

    print is_png(data)
    print get_image_info(data)

当你运行这个代码时,它会返回:

True
(x, y)

还有一个例子,包含了对JPEG格式的处理:http://markasread.net/post/17551554979/get-image-size-info-using-pure-python-code

70

Kurt的回答需要稍微调整一下才能适合我。

首先,在Ubuntu系统上,你可以用这个命令来安装:sudo apt-get install python-imaging

然后:

from PIL import Image

im = Image.open(filepath)
im.size # (width,height) tuple

想了解更多信息,可以查看这本手册

103

这里有一个Python 3的脚本,它可以返回一个包含图片高度和宽度的元组,支持的格式有.png、.gif和.jpeg,而且不需要使用任何外部库(也就是Kurt McKee提到的那些)。把这个脚本转到Python 2应该也比较简单。

import struct
import imghdr

def get_image_size(fname):
    '''Determine the image type of fhandle and return its size.
    from draco'''
    with open(fname, 'rb') as fhandle:
        head = fhandle.read(24)
        if len(head) != 24:
            return
        if imghdr.what(fname) == 'png':
            check = struct.unpack('>i', head[4:8])[0]
            if check != 0x0d0a1a0a:
                return
            width, height = struct.unpack('>ii', head[16:24])
        elif imghdr.what(fname) == 'gif':
            width, height = struct.unpack('<HH', head[6:10])
        elif imghdr.what(fname) == 'jpeg':
            try:
                fhandle.seek(0) # Read 0xff next
                size = 2
                ftype = 0
                while not 0xc0 <= ftype <= 0xcf:
                    fhandle.seek(size, 1)
                    byte = fhandle.read(1)
                    while ord(byte) == 0xff:
                        byte = fhandle.read(1)
                    ftype = ord(byte)
                    size = struct.unpack('>H', fhandle.read(2))[0] - 2
                # We are at a SOFn block
                fhandle.seek(1, 1)  # Skip `precision' byte.
                height, width = struct.unpack('>HH', fhandle.read(4))
            except Exception: #IGNORE:W0703
                return
        else:
            return
        return width, height

撰写回答