本文目录导读:

我来详细讲解如何使用Pillow库制作缩略图,包含多个实用案例。
基础安装
pip install Pillow
最简单的缩略图制作
from PIL import Image
def create_thumbnail(input_path, output_path, size=(150, 150)):
"""
制作缩略图
:param input_path: 输入图片路径
:param output_path: 输出图片路径
:param size: 缩略图大小 (宽, 高)
"""
# 打开图片
image = Image.open(input_path)
# 使用thumbnail方法(保持原比例)
image.thumbnail(size, Image.Resampling.LANCZOS)
# 保存缩略图
image.save(output_path, "JPEG", quality=85)
print(f"缩略图已保存至: {output_path}")
# 使用示例
create_thumbnail("input.jpg", "thumbnail.jpg")
固定尺寸裁剪缩略图
from PIL import Image
def create_fixed_thumbnail(input_path, output_path, size=(200, 200)):
"""
创建固定尺寸的缩略图,超出部分裁剪
"""
image = Image.open(input_path)
# 计算裁剪区域
image_ratio = image.width / image.height
target_ratio = size[0] / size[1]
if image_ratio > target_ratio:
# 图片太宽,裁剪左右
new_width = int(image.height * target_ratio)
left = (image.width - new_width) // 2
box = (left, 0, left + new_width, image.height)
else:
# 图片太高,裁剪上下
new_height = int(image.width / target_ratio)
top = (image.height - new_height) // 2
box = (0, top, image.width, top + new_height)
# 裁剪并调整大小
image = image.crop(box)
image.thumbnail(size, Image.Resampling.LANCZOS)
# 保存
image.save(output_path, "JPEG", quality=95)
print(f"固定尺寸缩略图已保存: {output_path}")
# 使用示例
create_fixed_thumbnail("input.jpg", "fixed_thumb.jpg")
批量处理缩略图
import os
from PIL import Image
from pathlib import Path
def batch_create_thumbnails(input_dir, output_dir, size=(150, 150), suffix="_thumb"):
"""
批量处理文件夹中的所有图片
"""
# 创建输出目录
Path(output_dir).mkdir(parents=True, exist_ok=True)
# 支持的图片格式
supported_formats = ['.jpg', '.jpeg', '.png', '.bmp', '.gif', '.webp']
processed_count = 0
for filename in os.listdir(input_dir):
file_ext = os.path.splitext(filename)[1].lower()
if file_ext in supported_formats:
# 构建路径
input_path = os.path.join(input_dir, filename)
output_filename = f"{os.path.splitext(filename)[0]}{suffix}{file_ext}"
output_path = os.path.join(output_dir, output_filename)
try:
# 处理图片
with Image.open(input_path) as img:
img.thumbnail(size, Image.Resampling.LANCZOS)
# 根据原格式保存
if file_ext in ['.jpg', '.jpeg']:
img.save(output_path, "JPEG", quality=85)
elif file_ext == '.png':
img.save(output_path, "PNG")
elif file_ext == '.gif':
img.save(output_path, "GIF")
else:
img.save(output_path)
processed_count += 1
print(f"处理完成: {filename} -> {output_filename}")
except Exception as e:
print(f"处理 {filename} 时出错: {e}")
print(f"\n批量处理完成! 共处理 {processed_count} 张图片")
# 使用示例
batch_create_thumbnails("original_images", "thumbnails", size=(200, 200))
添加水印的缩略图
from PIL import Image, ImageDraw, ImageFont
def create_thumb_with_watermark(input_path, output_path, size=(200, 200),
watermark_text="预览", font_size=20):
"""
创建带水印的缩略图
"""
image = Image.open(input_path)
# 创建缩略图
image.thumbnail(size, Image.Resampling.LANCZOS)
# 创建水印
watermark = Image.new('RGBA', image.size, (0, 0, 0, 0))
draw = ImageDraw.Draw(watermark)
# 设置字体
try:
font = ImageFont.truetype("arial.ttf", font_size)
except:
font = ImageFont.load_default()
# 计算水印位置(居中)
text_bbox = draw.textbbox((0, 0), watermark_text, font=font)
text_width = text_bbox[2] - text_bbox[0]
text_height = text_bbox[3] - text_bbox[1]
x = (image.width - text_width) // 2
y = (image.height - text_height) // 2
# 绘制半透明水印
draw.text((x, y), watermark_text, fill=(255, 255, 255, 128), font=font)
# 合并图片
result = Image.alpha_composite(image.convert('RGBA'), watermark)
# 保存
result = result.convert('RGB')
result.save(output_path, "JPEG", quality=85)
print(f"带水印缩略图已保存: {output_path}")
# 使用示例
create_thumb_with_watermark("input.jpg", "watermarked_thumb.jpg")
命令行工具版本
import argparse
from PIL import Image
import sys
def main():
parser = argparse.ArgumentParser(description='图片缩略图制作工具')
parser.add_argument('input', help='输入图片路径')
parser.add_argument('-o', '--output', default='thumbnail.jpg',
help='输出图片路径 (默认: thumbnail.jpg)')
parser.add_argument('-s', '--size', type=int, nargs=2,
default=[200, 200], metavar=('WIDTH', 'HEIGHT'),
help='缩略图尺寸 (默认: 200 200)')
parser.add_argument('-q', '--quality', type=int, default=85,
help='图片质量 1-100 (默认: 85)')
parser.add_argument('-k', '--keep-ratio', action='store_true',
help='保持原始比例')
args = parser.parse_args()
try:
with Image.open(args.input) as img:
if args.keep_ratio:
img.thumbnail(tuple(args.size), Image.Resampling.LANCZOS)
else:
img = img.resize(tuple(args.size), Image.Resampling.LANCZOS)
img.save(args.output, "JPEG", quality=args.quality)
print(f"缩略图已保存至: {args.output}")
except FileNotFoundError:
print(f"错误: 找不到文件 {args.input}")
sys.exit(1)
except Exception as e:
print(f"错误: {e}")
sys.exit(1)
if __name__ == "__main__":
main()
高级功能:自适应正方形缩略图
from PIL import Image
import math
def create_smart_square_thumb(input_path, output_path, size=200):
"""
智能裁剪为正方形缩略图,保留最重要的内容
"""
image = Image.open(input_path)
# 计算裁剪区域(基于边缘检测的中心裁剪)
width, height = image.size
if width > height:
# 横图:裁剪中间部分
left = (width - height) // 2
top = 0
right = left + height
bottom = height
else:
# 竖图:裁剪中间部分
left = 0
top = (height - width) // 2
right = width
bottom = top + width
# 裁剪为正方形
square_img = image.crop((left, top, right, bottom))
# 调整为指定大小
result = square_img.resize((size, size), Image.Resampling.LANCZOS)
# 保存
result.save(output_path, "JPEG", quality=95)
print(f"智能缩略图已保存: {output_path}")
# 使用示例
create_smart_square_thumb("input.jpg", "smart_thumb.jpg")
使用建议
- quality参数:JPG格式推荐85-95之间,平衡文件大小和画质
- Resampling.LANCZOS:高质量的缩放算法,适合缩略图
- 内存管理:处理大图片时使用
with语句自动释放资源 - 格式选择:透明背景用PNG,照片用JPG,动图用GIF
- 批量处理:注意处理异常,避免一个文件出错中断全部
这些案例涵盖了缩略图制作的常见场景,你可以根据实际需求选择合适的方案。