如何用PIL读取文件夹图片并存储到Python列表(需释放资源)
问题原因分析
你遇到的问题核心在于**with上下文管理器的特性**:当with Image.open(img_path) as img代码块执行完毕后,PIL会自动关闭这个Image对象并释放底层文件资源。此时你添加到列表中的img是已经被关闭的实例,无法再调用show()这类需要访问文件内容的方法;转numpy数组时也只会得到一个指向失效对象的容器,而非实际的像素数据。
两种正确实现方案
方案一:存储为Numpy数组(推荐,适合数据处理场景)
将图片内容转换为独立的Numpy数组存储,彻底脱离原文件句柄的依赖:
from pathlib import Path from PIL import Image import numpy as np path = Path("<path-to-folder>") list_of_images = [] for img_path in path.iterdir(): # 过滤非图片文件,避免报错 if img_path.suffix.lower() in ['.jpg', '.jpeg', '.png', '.bmp', '.gif']: with Image.open(img_path) as img: # 在with块内完成像素数据提取 img_array = np.array(img) list_of_images.append(img_array) # 测试使用 if list_of_images: # 从数组转回Image对象显示 Image.fromarray(list_of_images[0]).show() # 查看图片尺寸与通道信息 print(f"图片尺寸:{list_of_images[0].shape}")
方案二:复制PIL Image对象(保留PIL方法场景)
如果需要保留PIL Image对象的原生方法,可以在with块内复制对象,确保原对象关闭后副本仍有效:
from pathlib import Path from PIL import Image path = Path("<path-to-folder>") list_of_images = [] for img_path in path.iterdir(): if img_path.suffix.lower() in ['.jpg', '.jpeg', '.png', '.bmp', '.gif']: with Image.open(img_path) as img: # 复制Image实例,脱离原文件句柄 img_copy = img.copy() list_of_images.append(img_copy) # 测试使用 if list_of_images: list_of_images[0].show()
注意事项
- 必须添加文件后缀过滤逻辑,避免遍历到文件夹或非图片文件导致
Image.open()报错; - 两种方案都能保证原图片文件在读取后被及时关闭,释放系统资源;
- Numpy数组存储更适合机器学习、数值计算等场景,而复制PIL对象适合需要继续使用PIL图像处理API的场景。
内容的提问来源于stack exchange,提问作者Frosty726
相关产品推荐
相关产品推荐

