在 Python 中显示图像大小的正确方法是什么?

What is the correct approach to display the Image size in Python?

在循环中动态使用,这里有点问题。有几种方法可以获取以字节为单位的图像大小,只有一种方法可以提供准确的结果,但这需要将文件保存在磁盘中。如果我每次都保存磁盘并再次读取它,那么每次迭代都会花费双倍的精力。有没有办法准确读取图像结果?

from PIL import Image
import os
import sys

image = Image.open(image_path
size_kb = os.stat(image_path).st_size
buffer = BytesIO()
image.save(buffer, format="jpeg", quality = 100, optimize = True) # Does not save but acts like an image saved to disc
size_kb2 = (buffer.getbuffer().nbytes)

打印 3 个不同的结果 print(size_kb, size_kb2, sys.getsizeof(image.tobytes()),) 为同一图像提供了 3 个不同的结果,其中 os.stat 给出了准确的结果(与 Linux OS 显示的结果相同)

我不想把图片存盘再看,因为要花很多时间

整个代码:

STEP = 32
MIN_SIZE = 32

def resize_under_kb(image:Image,size_kb: float, desired_size:float)-> Image:
    '''
    Resize the image under given size in KB
    args:
        Image: Pil Image object
        size_kb: Current size of image in kb
        desired_size: Final desired size asked by user
    '''
    size = image.size
    new_width_height = max(size) - STEP # Decrease the pixels for first pass

    while new_width_height > MIN_SIZE and size_kb > desired_size: # either the image reaches minimun dimension possible or the desired possible size
        image = image.resize((new_width_height,new_width_height))  # keep on resizing until you get to desired output

        buffer = BytesIO()
        image.save(buffer, format="jpeg", quality = 100, optimize = True) # Does not save but acts like an image saved to disc
        size_kb = buffer.getbuffer().nbytes

        size = image.size # Current resized pixels
        new_width_height = max(size) - STEP # Dimensions for next iteration

    return image

此代码:

size_kb = os.stat(image_path).st_size

打印现有 JPEG 在磁盘上占用的字节数。


此代码:

buffer = BytesIO()
image.save(buffer, format="jpeg", quality = 100, optimize = True) # Does not save but acts like an image saved to disc
size_kb2 = (buffer.getbuffer().nbytes)

打印图像在保存时将在磁盘上占用的字节数...通过 PIL 当前的 JPEG 编码器,具有自己的霍夫曼表和质量以及 chroma-subsampling 并且不允许 file-system 最小值块大小。

这可能与您最初从磁盘读取的大小有很大不同,因为它可能是由不同的软件创建的,具有不同的速度和质量权衡。它甚至可能在两个版本的 PIL 之间有所不同。


此代码:

len(image.tobytes())

告诉您图像当前在内存中解压缩的字节数,不考虑图像所需的其他数据结构,也不考虑元数据(评论、GPS 数据、版权、制造商镜头数据和设置)数据)。