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. 警告产生的原因
这是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
相关产品推荐
相关产品推荐

