pin_drop当前位置:知识文库 ❯ 图文

Pillow图像缩放详解 - resize与thumbnail方法对比

概述

图像缩放是图像处理中的基础操作,Pillow提供了resize()thumbnail()两种缩放方式。resize()返回一个新的缩放后的Image对象,而thumbnail()直接在原图上修改。两者在内存使用和行为上有重要区别,理解它们的差异对于高效处理图像至关重要。


语法

代码示例

from PIL import Image

# resize方法
resized = img.resize(size, resample=None, box=None, reducing_gap=None)

# thumbnail方法
img.thumbnail(size, resample=None, reducing_gap=None)

参数说明

resize() 参数

参数 类型 必填 说明
size tuple 目标尺寸(width, height)
resample int 重采样滤波器,默认Image.BICUBIC
box tuple 类似crop的裁剪区域,先裁剪再缩放
reducing_gap float 缩减间隔,用于优化缩放质量

thumbnail() 参数

参数 类型 必填 说明
size tuple 最大尺寸(width, height)
resample int 重采样滤波器,默认Image.BICUBIC
reducing_gap float 缩减间隔

返回值

  • resize():返回一个新的Image对象,原图不变

  • thumbnail():无返回值,直接修改原图对象


重采样滤波器

滤波器 常量值 说明
NEAREST Image.NEAREST 最近邻,速度最快,质量最低
BILINEAR Image.BILINEAR 双线性插值,速度较快
BICUBIC Image.BICUBIC 双三次插值,质量较好(默认)
LANCZOS Image.LANCZOS Lanczos插值,质量最高,速度最慢

代码示例

示例1:使用resize缩放图像

代码示例

from PIL import Image

img = Image.new('RGB', (800, 600), color='skyblue')
print(f"原始尺寸: {img.size}")

# 等比缩放
resized = img.resize((400, 300))
print(f"缩放后尺寸: {resized.size}")

# 非等比缩放
stretched = img.resize((800, 300))
print(f"拉伸后尺寸: {stretched.size}")

# 使用不同滤波器
nearest = img.resize((200, 150), resample=Image.NEAREST)
lanczos = img.resize((200, 150), resample=Image.LANCZOS)
print(f"NEAREST缩放: {nearest.size}")
print(f"LANCZOS缩放: {lanczos.size}")

输出:

代码示例

原始尺寸: (800, 600)
缩放后尺寸: (400, 300)
拉伸后尺寸: (800, 300)
NEAREST缩放: (200, 150)
LANCZOS缩放: (200, 150)

示例2:使用thumbnail生成缩略图

代码示例

from PIL import Image

img = Image.new('RGB', (1920, 1080), color='coral')
print(f"原始尺寸: {img.size}")

# thumbnail保持宽高比,不会超过指定尺寸
img.thumbnail((200, 200))
print(f"缩略图尺寸: {img.size}")

# 注意:thumbnail返回None,直接修改原图
result = img.thumbnail((100, 100))
print(f"thumbnail返回值: {result}")
print(f"再次缩略后尺寸: {img.size}")

输出:

代码示例

原始尺寸: (1920, 1080)
缩略图尺寸: (200, 112)
thumbnail返回值: None
再次缩略后尺寸: (100, 56)

示例3:等比缩放工具函数

代码示例

from PIL import Image

def resize_by_ratio(img, ratio):
    """按比例缩放图像"""
    new_width = int(img.width * ratio)
    new_height = int(img.height * ratio)
    return img.resize((new_width, new_height))

def resize_by_width(img, target_width):
    """按宽度等比缩放"""
    ratio = target_width / img.width
    new_height = int(img.height * ratio)
    return img.resize((target_width, new_height))

img = Image.new('RGB', (1000, 800), color='gold')
print(f"原始尺寸: {img.size}")

half = resize_by_ratio(img, 0.5)
print(f"缩小50%: {half.size}")

by_width = resize_by_width(img, 300)
print(f"宽度300等比缩放: {by_width.size}")

输出:

代码示例

原始尺寸: (1000, 800)
缩小50%: (500, 400)
宽度300等比缩放: (300, 240)

实际应用场景

  • 场景1:电商网站生成商品缩略图,统一展示尺寸

  • 场景2:移动端适配,将高清图片缩小到适合手机屏幕的尺寸

  • 场景3:图片懒加载,先加载缩略图再按需加载原图


注意事项

注意thumbnail()直接修改原图且返回None,如果需要保留原图请先copy()

注意thumbnail()只会缩小不会放大,如果原图小于指定尺寸则不会改变

注意resize()可以放大图像,但放大会导致模糊,应尽量避免

注意:缩放后尺寸必须为正整数,浮点数会被截断


resize与thumbnail对比

特性 resize() thumbnail()
返回值 新Image对象 None
原图是否改变 不改变 直接修改
是否保持比例 否(默认不保持)
能否放大 不能
内存占用 较高(同时存在两图) 较低

小结

  • resize()返回新对象,灵活但内存占用较高;thumbnail()原地修改,适合批量生成缩略图

  • 缩放时选择合适的重采样滤波器,LANCZOS质量最高,NEAREST速度最快

  • 实际开发中推荐编写等比缩放工具函数,避免图像变形


练习题

练习1

编写程序,打开一张图片,分别按50%和25%比例缩小,保存为两个文件

练习2

编写一个函数,接收Image对象和目标宽度,按宽度等比缩放并返回新Image对象

常见问题

resize和thumbnail的主要区别是什么?

resize()返回新对象不修改原图,可任意缩放;thumbnail()原地修改返回None,只缩小不放大且保持比例。

如何选择合适的重采样滤波器?

LANCZOS质量最高适合高质量缩略图;BICUBIC默认选项平衡质量与速度;NEAREST速度最快适合像素艺术或需要保持锐利边缘的场景。

为什么thumbnail后原图变小了?

thumbnail()是原地操作,直接修改原图对象。如需保留原图,应先调用img.copy()创建副本再操作。

标签: Pillow 图像缩放 resize thumbnail 图像处理

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: Pillow Image.crop()裁剪教程 - 图像裁剪方法详解 下一篇: Pillow Image旋转教程 - rotate()与transpose()方法详解

poll相关推荐