Python怎么用Pillow读取图片文件

桃夭
桃夭
发布时间:2026-11-05| 8人浏览过
原创

详细讲解在Python中使用Pillow库读取图片文件的方法与操作步骤,涵盖Image.open基础用法、图像属性获取、惰性加载机制、内存流读取及常见异常排查。

一、环境准备与模块导入

在编写代码前,需要确保当前 Python 环境已安装 Pillow。Pillow 是早已停止维护的经典 Python Imaging Library(PIL)的现代活跃分支,兼容常见的 JPEG、PNG、WebP、BMP、TIFF 等主流图片格式。

1. 安装 Pillow

打开终端或命令行,执行如下 pip 安装指令:

pip install Pillow

这里的包名是 Pillow。安装过程会自动包含对应操作系统平台的预编译 C 扩展与图像解码动态库。

2. 导入核心类 Image

编写 Python 脚本时,必须注意:导入的命名空间为 PIL(大写),而不是小写的 pillow。Pillow 保持了与早期 PIL 相同的顶层包名设计。

# 正确导入方式
from PIL import Image

# 常见错误:请勿写成 import pillow 或 import Image
Python怎么用Pillow读取图片文件
图 2:Pillow 读取图片文件的四步标准化操作全流程

二、核心方法:使用 Image.open() 打开图片

读取图片文件的核心函数是 Image.open()。该函数接收一个文件路径字符串(或 pathlib.Path 对象、亦或二进制文件对象),返回一个 PIL.Image.Image 实例。

1. 标准推荐写法:使用 with 语句

因为读取图片涉及底层操作系统文件句柄,强烈建议配合 with 语句使用上下文管理:

from PIL import Image

with Image.open("example.jpg") as img:
    # 打印图像基本属性
    print("图片格式 (format):", img.format)
    print("图片尺寸 (size):", img.size)
    print("色彩模式 (mode):", img.mode)

    # 弹出系统默认看图工具预览
    img.show()
示例输出:
图片格式 (format): JPEG
图片尺寸 (size): (1920, 1080)
色彩模式 (mode): RGB

2. 核心属性说明

  • img.format:图像编码格式,例如 'JPEG'、'PNG'、'GIF'。若图片由内存生成而非从文件打开,该属性值可能为 None。
  • img.size:包含两个整数的二元元组 (width, height),单位为像素。注意宽度在前,高度在后。
  • img.mode:图像的色彩通道模式,常见有 'RGB'(24位真彩色)、'RGBA'(带透明度)、'L'(8位灰度图)等。
  • img.show():主要用于开发调试。该方法会将图片写入系统临时文件,并调用系统内置图片查看器快速弹出窗口展示。

三、深度解析:惰性加载(Lazy Loading)与生命周期

理解 Pillow 的读取机制,关键在于认识到 Image.open() 是一种惰性加载(Lazy Operation)。

当执行 img = Image.open("huge_photo.jpg") 时,Pillow 实际上并没有把整张图片的所有像素数据解压到内存中,而仅仅是读取了文件开头的几十或上百个字节(Header)。通过解析文件头,Pillow 就能获知图像格式、宽高及色彩模式。因此,无论图片体积是几百 KB 还是几十 MB,open() 都能在毫秒级内完成。

Python怎么用Pillow读取图片文件
图 3:Pillow 惰性加载机制与内存生命周期对照

为什么必须注意文件句柄与 img.load()?

正因为像素数据没有立刻载入,图像对象在底层仍然持续持有对磁盘文件的引用句柄。只有当后续调用如 img.show()、img.crop()、img.save(),或者主动调用 img.load() 时,Pillow 才会真正启动解码器,解压整张图片的像素矩阵。

常见陷阱:如果使用了 with Image.open(...) as img:,在跳出 with 代码块的瞬间,文件句柄就会被强制关闭。如果在退出 with 之后再去访问像素,可能会抛出 ValueError: seek of closed file。
解决办法:如果需要在退出上下文后继续操作图像,请在退出前执行 img.load(),强制将像素完全载入内存:
from PIL import Image

with Image.open("example.png") as file_img:
    file_img.load()  # 强制解码全部像素至内存
    img = file_img.copy()

# 离开 with 块后,文件句柄已释放,但 img 依然可以在内存中自由处理
print(img.size)

四、进阶场景:内存流读取与多帧动图处理

实际项目中,除了读取本地磁盘路径外,经常遇到从网络 API 获取图片数据,或者读取 GIF 动图等场景。

Python怎么用Pillow读取图片文件
图 4:多样化输入源处理与常用图像色彩模式对照

1. 从内存二进制流(BytesIO)中读取

当使用 requests 或 urllib 从网络下载图片后,不需要先存为本地临时文件,可以直接使用 Python 标准库的 io.BytesIO 包装字节流后交给 Pillow:

import io
import urllib.request
from PIL import Image

url = "https://example.com/sample.jpg"
with urllib.request.urlopen(url) as response:
    image_bytes = response.read()

# 使用 io.BytesIO 将 bytes 转化为内存文件对象
with Image.open(io.BytesIO(image_bytes)) as img:
    print("从网络流读取成功:", img.size, img.format)

2. 读取多帧图像(GIF / TIFF)

对于包含多帧画面的动图或多页文档,Pillow 提供了 n_frames 属性和 seek() 方法实现逐帧遍历:

from PIL import Image

with Image.open("animation.gif") as img:
    total_frames = getattr(img, "n_frames", 1)
    print(f"动图总帧数: {total_frames}")

    for frame_idx in range(total_frames):
        img.seek(frame_idx)  # 定位到对应帧
        print(f"当前帧: {img.tell()}, 尺寸: {img.size}")

3. 色彩模式转换注意点

如果读取的是带 Alpha 透明通道的 PNG 图片(模式为 RGBA),当需要将其另存为 JPEG 格式时,必须先进行模式转换。因为 JPEG 格式不支持透明通道,直接保存会抛出 OSError: cannot write mode RGBA as JPEG:

with Image.open("transparent_logo.png") as img:
    if img.mode in ("RGBA", "P"):
        # 转换为 RGB 格式,去除透明通道
        rgb_img = img.convert("RGB")
        rgb_img.save("logo.jpg", "JPEG")

五、常见报错与排查诊断

在使用 Image.open() 读取图片过程中,最常遇到的三类异常及排查方法如下:

Python怎么用Pillow读取图片文件
图 5:常见异常诊断树与生产读图最佳实践速查
异常类型 常见诱发原因 推荐应对方案
FileNotFoundError 相对路径与当前终端工作目录不一致;Windows 系统下反斜杠转义混淆。 使用 pathlib.Path(__file__).parent 构建基准绝对路径;路径字符串前加 r""。
UnidentifiedImageError 文件虽有 .jpg 后缀但实际为损坏文件、HTML 错误页或空文件。 使用 try...except UnidentifiedImageError 捕获;校验文件前几个字节(Magic Number)。
DecompressionBombError 图片像素过大(默认超过约 8947 万像素),触发防解压炸弹保护。 确认图片可信后,设置 Image.MAX_IMAGE_PIXELS = None 允许读取特大图像。

路径排查实操建议

避免硬编码相对路径 "pic.jpg"。推荐统一使用现代标准的 pathlib 库定位脚本同级目录下的资源文件:

from pathlib import Path
from PIL import Image

# 获取当前脚本所在目录
base_dir = Path(__file__).resolve().parent
image_path = base_dir / "assets" / "demo.jpg"

if image_path.exists():
    with Image.open(image_path) as img:
        print("成功加载:", img.size)
else:
    print("文件未找到:", image_path)

六、总结速查表

掌握 Pillow 读取图片文件,核心要点可归结为以下清单:

  1. 安装与导入:安装执行 pip install Pillow,代码导入写 from PIL import Image。
  2. 基础调用:优先使用 with Image.open(path) as img: 上下文管理器,自动管理底层文件生命周期。
  3. 属性获取:通过 img.size 获取二元宽高元组,img.format 获取文件格式,img.mode 获取色彩通道。
  4. 性能特性:open() 采用惰性加载,仅解析文件头;脱离上下文前若需继续处理像素,需先执行 img.load()。
  5. 格式兼容:PNG 转存 JPEG 需先调用 img.convert('RGB'),内存数据流可通过 io.BytesIO 无缝加载。

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

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 算法库。