【问题标题】:How to get image size (bytes) using PIL如何使用 PIL 获取图像大小(字节)
【发布时间】:2012-08-07 21:33:51
【问题描述】:

我发现了如何使用 PIL 来获取图像尺寸,而不是文件大小(以字节为单位)。我需要知道文件大小来决定文件是否太大而无法上传到数据库。

【问题讨论】:

  • 您是在生成图像,还是将图像存储在磁盘上?
  • 使用文件系统 API 获取文件大小,而不是 PIL。
  • len(),如果您将其保存在内存中而不是文件系统中(如果您将其作为 BLOB 存储在数据库中,这似乎很可能。)
  • 使用StringIO获取流量。

标签: python python-imaging-library tornado filesize


【解决方案1】:

试试:

import os
print os.stat('somefile.ext').st_size

【讨论】:

  • 现在有办法使用 PIL 本身吗?
  • 为什么需要使用 PIL?
  • 来控制是否是图片而不是伪造的图片头,制作上传配置文件,然后将其存储到数据库中,所以很明显在PIL中制作一个方法来获取以字节为单位的大小没有?
  • 不,一点也不明显。 PIL 处理内存中的图像操作,为此它使用对操作像素有效的内部表示。这种表示可能会或可能不会对应于图像保存为特定格式时的大小......
  • 但我认为在转换为字节时大小隐藏在图像头文件中的某处?喜欢它的扩展名吗?
【解决方案2】:

我对此有点晚了,但我在 5 分钟前在搜索如何获取 PIL 图像的大小而不将其保存到磁盘时遇到了这个问题。万一其他人遇到这种情况,这是一种简单的方法:

import StringIO
output = StringIO.StringIO()
image_output.save(output, 'PNG') #a format needs to be provided
contents = output.getvalue()
output.close()

image_filesize = len(contents)

【讨论】:

    【解决方案3】:

    如果您已经在文件系统上拥有该图像:

    import os
    os.path.getsize('path_to_file.jpg')`
    

    但是,如果您想获取内存中尚未保存到文件系统的图像的保存大小:

    from io import BytesIO
    img_file = BytesIO()
    image.save(img_file, 'png')
    image_file_size = img_file.tell()
    

    此方法将避免与 StringIO 一样多次读取图像数据。但是请注意,它将使用更多 RAM。一切都是权衡。 :-)

    编辑:我刚从 OP 看到这条评论:

    最后,问题是从一开始,如果有人会上传一个 图片有 1 giga(伪造的)他会在 PIL 之前杀死服务器 会做它的事情,所以我必须在它完成之前阻止请求!

    这是一个非常不同的问题,可能最好在 Web 服务器上完成。对于 nginx,您可以将其添加到您的配置中:

    http {
        #...
            client_max_body_size 100m; # or whatever size you want as your limit
        #...
    }
    

    【讨论】:

    • BytesIO 方法与从桌面获取尺寸相比似乎低估了尺寸。知道为什么吗?
    【解决方案4】:

    我认为这是内存中图像大小(以字节为单位)的真正衡量标准和最快的衡量标准:

    print("img size in memory in bytes: ", sys.getsizeof(img.tobytes()))
    

    那么,磁盘上文件的大小取决于文件的格式:

    from io import BytesIO
    img_file = BytesIO()
    img.save(img_file, 'png')
    img_file_size_png = img_file.tell()
    img_file = BytesIO()
    img.save(img_file, 'jpeg')
    img_file_size_jpeg = img_file.tell()
    print("img_file_size png: ", img_file_size_png)
    print("img_file_size jpeg: ", img_file_size_jpeg)
    

    来自 CIFAR10 数据集的 32 x 32 x 3 图像的可能输出:

    img size in memory in bytes:  3105    
    img_file_size png:  2488
    img_file_size jpeg:  983
    

    【讨论】:

    • sys.getsizeof() 大大高估了 jpeg 文件,高估了 webp 文件。对于我测试的 png 文件,它工作正常。也可以只调用img.tobytes().__sizeof__(),但这些方法似乎都不可靠。
    【解决方案5】:

    要使用枕头库查找图像的大小(以字节为单位),请使用以下代码。它会正常工作。

    from PIL import Image
    image_file = Image.open(filename)
    print("File Size In Bytes:- "+str(len(image_file.fp.read()))
    

    确保您已安装枕头库:-

    pip install pillow
    

    【讨论】:

    • 如果您修改了图像(例如使用调整大小)并且没有将图像保存到磁盘,这将不起作用。
    猜你喜欢
    • 2011-09-20
    • 2023-03-05
    • 2017-04-01
    • 1970-01-01
    • 2019-03-11
    • 2016-10-04
    • 1970-01-01
    • 2012-12-01
    • 2015-12-17
    相关资源
    最近更新 更多