Python怎么批量读取文件夹内的所有图片

巷口听风
巷口听风
发布时间:2026-10-30| 7人浏览过
原创

详细讲解在Python中批量读取文件夹内所有图片的实用方法,包含pathlib、os.walk、Pillow与OpenCV的完整代码实现、多级子目录递归、中文路径容错及生成器内存优化。

在 Python 中批量读取文件夹内的图片,本质上分为两个独立阶段:首先是文件路径检索与筛选,找到目标目录下所有合法的图片文件;其次是数据载入与内存管理,根据任务需求选用 Pillow、OpenCV 或生成器按需解析图片数据。最推荐且符合现代 Python 规范的实现是使用标准库 pathlib 搭配 Pillow 库,兼顾代码优雅性、跨平台兼容与执行稳定性。

Python怎么批量读取文件夹内的所有图片
图 1:Python 批量读取图片的四个核心步骤与数据流向

一、推荐做法:使用 pathlib 与 Pillow 批量读取

pathlib 是 Python 3 内置的标准库,面向对象地管理路径,能自动处理 Windows 反斜杠与 Linux 正斜杠的差异;Pillow(导入名为 PIL)则是 Python 处理图片最主流的第三方库。安装命令非常直接:

pip install Pillow

1. 读取当前文件夹下的所有图片(非递归)

如果图片都在同一个文件夹的一级目录下,不需要扫描子文件夹,可以使用 Path.iterdir() 或 Path.glob():

from pathlib import Path
from PIL import Image

def load_images_from_folder(folder_path):
    # 支持的常见图片后缀,转小写对比
    valid_extensions = {".jpg", ".jpeg", ".png", ".bmp", ".webp"}
    images = []
    
    target_dir = Path(folder_path)
    if not target_dir.is_dir():
        print(f"指定的目录不存在: {folder_path}")
        return images

    # 遍历该目录下的直接子文件
    for item in target_dir.iterdir():
        if item.is_file() and item.suffix.lower() in valid_extensions:
            try:
                # 使用 with 上下文确保读取数据后关闭底层文件句柄
                with Image.open(item) as img:
                    # 复制一份图像数据到内存中,避免上下文退出后文件句柄关闭失效
                    images.append((item.name, img.copy()))
            except Exception as e:
                print(f"无法读取图片 {item.name}: {e}")

    print(f"成功读取 {len(images)} 张图片")
    return images

# 调用示例
# image_list = load_images_from_folder("./photos")

2. 递归读取包含多级子目录的所有图片

当图片分散存放在多级子分类文件夹中时,可以使用 Path.rglob("*") 进行深度递归遍历:

from pathlib import Path
from PIL import Image

def load_images_recursively(folder_path):
    valid_extensions = {".jpg", ".jpeg", ".png", ".bmp", ".webp"}
    target_dir = Path(folder_path)
    
    loaded_data = []
    # rglob("*") 递归检索所有层级的子文件
    for file_path in target_dir.rglob("*"):
        if file_path.is_file() and file_path.suffix.lower() in valid_extensions:
            try:
                with Image.open(file_path) as img:
                    loaded_data.append({
                        "path": str(file_path),
                        "size": img.size,      # (宽, 高)
                        "mode": img.mode,      # RGB / RGBA / L
                        "image": img.copy()
                    })
            except Exception as e:
                print(f"文件损坏或无法解析: {file_path},原因: {e}")

    return loaded_data

二、主流读取方案的技术选型与对比

在面对不同体量、不同结构和不同业务场景时,Python 提供了多种工具组合。下表和对比图给出了主流方案的特性分析:

Python怎么批量读取文件夹内的所有图片
图 2:主流批量读取方案在依赖、内存表现、速度及应用场景的横向对比

三、海量图片场景:生成器(Generator)与内存优化

当文件夹包含几万张高分辨率图片时,严禁使用列表把所有图片一次性 append 进来。每张 4K 图片解码后占用的内存可能高达数十兆,几千张图片就会消耗几十 GB 内存导致系统发生 OOM(内存溢出崩溃)。

Python怎么批量读取文件夹内的所有图片
图 3:一次性全量加载与生成器流式处理在内存占用上的本质区别

使用 Python 关键字 yield 将函数改造为生成器:读一张、处理一张、释放一张,内存始终处于安全稳定状态:

from pathlib import Path
from PIL import Image

def image_stream(folder_path):
    """生成器:逐张产出图片路径与图像对象,避免内存占用过大"""
    valid_exts = {".jpg", ".jpeg", ".png", ".webp"}
    for p in Path(folder_path).rglob("*"):
        if p.is_file() and p.suffix.lower() in valid_exts:
            try:
                # 仅在需要时打开图片
                with Image.open(p) as img:
                    yield p, img
            except Exception as err:
                print(f"跳过不可读文件 {p}: {err}")

# 使用方式:消费生成器
# for path, img in image_stream("./large_dataset"):
#     # 执行当前图像的处理逻辑(如缩放、特征提取或保存)
#     print(f"处理完成: {path.name}, 尺寸: {img.size}")
#     # 循环单次结束,img 离开作用域被垃圾回收

四、避坑指南:中文路径、损坏文件与特殊格式

1. OpenCV 中文路径读取失败问题

在使用 cv2.imread() 读取图片时,如果文件路径中包含中文字符,在 Windows 系统下经常会直接返回 None 而不报错。推荐的通用解决方案是先用 np.fromfile 读取二进制字节流,再通过 cv2.imdecode 解码:

import cv2
import numpy as np
from pathlib import Path

def cv2_read_image(image_path):
    """支持中文路径与特殊字符的 OpenCV 图像读取函数"""
    try:
        # np.fromfile 支持包含中文的文件路径
        img_array = np.fromfile(str(image_path), dtype=np.uint8)
        # 解码为彩色图像 (BGR)
        img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
        return img
    except Exception as e:
        print(f"解码失败: {image_path}, 错误: {e}")
        return None

# 批量搭配使用
def batch_read_opencv(folder):
    for p in Path(folder).glob("*.jpg"):
        img = cv2_read_image(p)
        if img is not None:
            # 正常处理 (OpenCV 读取出的形状为 H x W x C)
            h, w, c = img.shape

2. 常见异常捕获与过滤

文件夹中常常混入重命名伪装文件(如将文本文件改后缀为 .jpg)、被操作系统锁定的临时文件(如 macOS 下的 ._DS_Store 或 ._*.jpg)。建议在遍历时加入前缀过滤:

# 排除系统隐藏文件和 macOS 资源分支文件
if file_path.name.startswith((".", "._")):
    continue

五、实战总结与决策指南

针对不同开发需求,可参考以下路径直接锁定最合适你的代码组合:

Python怎么批量读取文件夹内的所有图片
图 4:根据数据规模与业务场景快速选用最佳实践代码
核心记忆点:遍历路径选 pathlib.Path.rglob(),打开图片用 with Image.open(),量大必用 yield 生成器,遇中文路径选 np.fromfile + cv2.imdecode。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。