You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python像素转厘米代码触发DecompressionBombWarning问题排查

关于PIL的DecompressionBombWarning警告及高效像素转换问题

问题背景

用户使用以下Python代码将图片像素尺寸转换为厘米(设定1cm=37.79527559055像素,不依赖DPI):

if self.digital:
   im = Image.open(os.path.join(folder, filename))
   width, height = im.size
   image_info["width"] = round(width / 37.79527559055, 0)

运行时触发警告:

Python311\Lib\site-packages\PIL\Image.py:3167: DecompressionBombWarning: Image size (130437549 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS attack.

用户有两个疑问:

  1. 该警告产生的原因是什么?
  2. 是否存在比用临时列表存储像素值再转换更高效的方法?

解答

1. 警告产生的原因

这是PIL库的安全防护机制:当图片总像素数超过默认阈值(89478485,约2990×2990像素)时,会触发DecompressionBombWarning。它的作用是防范解压炸弹攻击——这类攻击通过构造体积极小但解压后像素量极大的图片,占用大量内存和CPU资源,导致程序甚至系统崩溃。

你的图片总像素数达到130437549,超过了默认限制,因此触发该警告。

2. 更高效的尺寸转换方法

首先要明确:你当前的代码已经是最优解——Image.open()默认不会立即加载整张图片的像素数据到内存,仅读取图片元信息(包括尺寸)。你只获取了im.size,完全不需要存储任何像素值,这已经是最高效的方式。

如果是想处理警告本身,有两种可行方案:

  • 临时屏蔽警告:若确认图片安全,可通过warnings模块禁用该警告:
    import warnings
    from PIL import Image
    
    warnings.filterwarnings("ignore", category=Image.DecompressionBombWarning)
    
    # 原有代码逻辑
    if self.digital:
        im = Image.open(os.path.join(folder, filename))
        width, height = im.size
        image_info["width"] = round(width / 37.79527559055, 0)
    
  • 调整PIL的像素上限:修改全局阈值,允许处理更大尺寸的图片:
    from PIL import Image
    
    # 自定义像素上限,例如设为2亿像素
    Image.MAX_IMAGE_PIXELS = 200000000
    
    # 原有代码逻辑
    if self.digital:
        im = Image.open(os.path.join(folder, filename))
        width, height = im.size
        image_info["width"] = round(width / 37.79527559055, 0)
    

注意:调整上限前需确保系统有足够内存处理大图片,避免内存溢出。

内容的提问来源于stack exchange,提问作者Pythonmaru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 15:15:32