Image.open() 惰性加载,.size 首次访问才解析尺寸并可能抛错;返回 (width, height) 元组,需 try/except 捕获并 close() 释放资源。

Image.open() 本身不读取尺寸,必须调用 .size 才能拿到宽高
很多人以为 Image.open() 返回对象时就“加载完所有元数据”,其实它默认只解码文件头,.size 是第一次访问时才真正解析图像尺寸(惰性加载)。不访问 .size,就不会触发尺寸读取。
- 直接打印
img对象看不到尺寸,只会显示类似<pil.jpegimageplugin.jpegimagefile image mode="RGB" size="..."></pil.jpegimageplugin.jpegimagefile>—— 这个size=...是 repr 里临时调用的,不是你“没做任何事”就有的 - 如果文件损坏或格式异常,
.size第一次访问时才会抛出IOError或ValueError,而不是open()那一刻 - 想只读尺寸不加载像素数据?不行。
.size虽轻量,但仍需部分解析;真要零解码,得用imghdr或手动读文件头(不推荐,Pillow 已覆盖绝大多数场景)
用 .size 拿到的是 (width, height) 元组,不是 dict 或属性字符串
返回值固定是二元元组:(width, height),顺序不能反。有人误以为是 {'w': ..., 'h': ...} 或想用 .width 属性,结果报 AttributeError。
-
img.size[0]是宽度(像素),img.size[1]是高度(像素) - 别写
img.width或img.get_size()—— 这些都不存在 - 需要命名更清晰?可以解包:
width, height = img.size,但别绕开.size
图片未关闭或路径错误时,.size 可能延迟报错或返回意外结果
Image.open() 不校验文件是否可读、是否真为图像,直到你访问 .size 或其他属性(如 .mode)才真正尝试解析。这时候出问题,错误位置容易误判。
- 路径拼错、文件被占用、权限不足 → 访问
.size时抛IOError: cannot identify image file或OSError: [Errno 2] No such file - 传入了空文件、txt 文件、zip 文件 → 同样在
.size触发时报IOError: cannot identify image file - 用完记得
img.close()(尤其循环处理大量图时),否则可能遇到“too many open files”系统错误 ——.size本身不释放句柄
读取尺寸前,建议先用 try/except 包住 .size 访问
因为尺寸获取是首个实际 I/O 解析点,也是最常暴露问题的地方。与其让程序崩在后续逻辑,不如在这里捕获并区分处理。
立即学习“Python免费学习笔记(深入)”;
from PIL import Image
<p>try:
img = Image.open("photo.jpg")
width, height = img.size # ← 真正解析发生在这里
except (IOError, OSError) as e:
print(f"无法读取图片尺寸:{e}")
finally:
if 'img' in locals():
img.close()- 不要只 catch
IOError,OSError在 Python 3.3+ 中已覆盖文件系统类错误 - 避免用
os.path.exists()提前判断——它不能代替 Pillow 对文件内容的校验 - 批量处理时,即使某张图失败,也不影响下一张;但忘记
close()容易累积资源泄漏
尺寸读取看着简单,但它的“懒加载”特性决定了错误总在你以为安全的地方冒出来;而且一旦漏关文件,问题会从单张图蔓延成整个进程卡死。










