当前位置:首页>python>一起学Python第122天:Pillow 入门实战——一条流水线串起图像处理全流程

一起学Python第122天:Pillow 入门实战——一条流水线串起图像处理全流程

  • 2026-10-11 06:57:30
一起学Python第122天:Pillow 入门实战——一条流水线串起图像处理全流程

📅 系列:一起学Python | 难度:⭐⭐ | 预计阅读:8分钟

🔗 上期回顾:第121天:Pillow 隐藏技能

一、为什么需要"一条流水线"?

前面四天,我们把 Pillow 拆成了碎片学习:打开、裁剪、缩放、滤镜、增强、水印……但真正工作中,这些操作是串在一起的。

比如老板给你一个任务:"把这张产品图裁成正方形、缩成800×800、调亮一点、加个Logo水印、保存为PNG。"

如果你只会单个操作,就要写一堆零散代码。今天这期,我们把 Pillow 的核心基础操作串成一条流水线——从打开到成品,一气呵成。

二、前置准备:网络图片加载 + 字体配置

from PIL import Image, ImageDraw, ImageFont, ImageFilter, ImageEnhancefrom io import BytesIOimport requestsimport os# ================= 1. 字体加载(解决报错的核心) =================font_path = "simhei.ttf"  # 确保当前目录有 simhei.ttfif not os.path.exists(font_path):    font_path = "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc"  # 备用系统字体# Pillow 使用 ImageFont.truetype 加载font = ImageFont.truetype(font_path, size=24)# 通用加载函数:从网络URL读取图片def load_image(url):    resp = requests.get(url, timeout=15)    return Image.open(BytesIO(resp.content)).convert('RGB')

三、第一步:打开图片,读懂它的"身份证"

url = "https://picsum.photos/600/600"img = load_image(url)print(f"格式: {img.format}")   # JPEG / PNG / GIFprint(f"尺寸: {img.size}")     # (宽, 高)print(f"模式: {img.mode}")     # RGB / RGBA / L(灰度)
Image 对象三大属性速查:
属性
含义
常见值
format
文件格式
'JPEG'、'PNG'、'GIF'
size
像素尺寸
(800, 600)→ 宽800,高600
mode
颜色模式
RGB
(彩色)、RGBA(带透明)、L(灰度)
💡 为什么先 convert('RGB')?网络图片可能是 RGBA 或 P 模式,统一转 RGB 避免后续处理报错。

四、第二步:格式转换——给图片"换身份"

# 转灰度gray = img.convert('L')gray.show()# 转回 RGB(灰度图转彩色,但仍是黑白)rgb_back = gray.convert('RGB')rgb_back.show()# 保存为不同格式img.save("output.png")                    # 自动识别格式img.save("output.jpg", quality=95)        # JPEG 控制质量img.save("output.webp", quality=85)       # WebP 更小体积
🔥 WebP 优势:相同质量下,体积比 JPEG 小 25-35%,现代浏览器全支持。

五、第三步:裁剪与旋转——重新构图

裁剪:取局部精华

# crop((左, 上, 右, 下))cropped = img.crop((150, 150, 450, 450))cropped.show()

旋转:调整角度

# 旋转45度,expand=True 扩展画布防止裁剪rotated = img.rotate(45, expand=True)rotated.show()
💡 坐标记忆法:crop((left, upper, right, bottom)),先左上角,后右下角。

六、第四步:缩放——resize vs thumbnail 怎么选?

# 方法1:resize —— 强制指定尺寸(可能变形)resized = img.resize((300, 300))  # 原图600x600 → 强行拉成300x300# 方法2:thumbnail —— 保持比例,原地修改thumb = img.copy()thumb.thumbnail((300, 300))  # 按比例缩放,长边不超过300
方法
特点
适用场景
resize((w,h))
强制变形,精确控制
需要固定像素尺寸
thumbnail((w,h))
保持比例,原地修改
生成缩略图,不拉伸

七、第五步:滤镜与增强——一键"美颜"

滤镜(ImageFilter)

from PIL import ImageFilterblur = img.filter(ImageFilter.GaussianBlur(radius=5))edge = img.filter(ImageFilter.FIND_EDGES)emboss = img.filter(ImageFilter.EMBOSS)sharpen = img.filter(ImageFilter.SHARPEN)

增强(ImageEnhance)

from PIL import ImageEnhancebright = ImageEnhance.Brightness(img).enhance(1.5)   # 亮度 x1.5contrast = ImageEnhance.Contrast(img).enhance(2.0)   # 对比度 x2.0color = ImageEnhance.Color(img).enhance(2.0)         # 饱和度 x2.0sharp = ImageEnhance.Sharpness(img).enhance(2.5)     # 锐度 x2.5
💡 enhance(factor) 参数:1.0 = 原图,<1 = 减弱,>1 = 增强。建议范围 0.5 ~ 2.5。

八、第六步:绘图与文字——给图片"签名"

# 创建画笔draw = ImageDraw.Draw(img)# 绘制形状draw.rectangle([50, 50, 200, 200], outline="red", width=5)draw.line([0, 0, 300, 300], fill="blue", width=3)draw.ellipse([250, 250, 450, 450], outline="green", width=4)# 添加文字(必须加载中文字体!)font = ImageFont.truetype(font_path, size=40)draw.text((50, 50), "Hello Pillow", fill="red", font=font)draw.text((50, 500), "第122天", fill="yellow", font=font)

九、综合实战:一条流水线搞定"裁-缩-调-印-存"

把以上所有步骤串起来,写一个完整的图像处理函数:

from PIL import Image, ImageDraw, ImageFont, ImageEnhancefrom io import BytesIOimport requestsimport os# ================= 1. 字体加载(解决报错的核心) =================font_path = "simhei.ttf"if not os.path.exists(font_path):    font_path = "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc"font = ImageFont.truetype(font_path, size=20)def process_pipeline(url, output_path):    """    图像处理流水线:    下载 → 裁剪 → 缩放 → 调亮 → 加水印 → 保存    """    # Step 1: 下载    resp = requests.get(url, timeout=15)    img = Image.open(BytesIO(resp.content)).convert('RGB')    print(f"原图: {img.size}")    # Step 2: 居中裁剪为正方形    w, h = img.size    size = min(w, h)    left = (w - size) // 2    top = (h - size) // 2    img = img.crop((left, top, left + size, top + size))    print(f"裁剪后: {img.size}")    # Step 3: 缩放到 800x800    img = img.resize((800, 800), Image.LANCZOS)    # Step 4: 调亮 20%    enhancer = ImageEnhance.Brightness(img)    img = enhancer.enhance(1.2)    # Step 5: 加水印    draw = ImageDraw.Draw(img)    text = "一起学Python"    bbox = draw.textbbox((0, 0), text, font=font)    text_w = bbox[2] - bbox[0]    text_h = bbox[3] - bbox[1]    x = img.width - text_w - 20    y = img.height - text_h - 20    draw.rectangle([x-10, y-5, x+text_w+10, y+text_h+5], fill=(0, 0, 0, 128))    draw.text((x, y), text, fill="white", font=font)    # Step 6: 保存    img.save(output_path, quality=95)    print(f"✅ 已保存: {output_path}")    # 显示结果    img.show()# 使用process_pipeline("https://picsum.photos/1000/800", "final_output.jpg")

十、批量处理:从"一张"到"一百张"

import globdef batch_process(url_list, output_dir="output"):    os.makedirs(output_dir, exist_ok=True)    for i, url in enumerate(url_list):        try:            process_pipeline(url, f"{output_dir}/img_{i+1}.jpg")        except Exception as e:            print(f"处理失败 {url}: {e}")# 批量处理urls = [f"https://picsum.photos/800/600?random={i}" for i in range(5)]batch_process(urls)

十一、避坑指南

十二、参数速查卡

from PIL import Image, ImageDraw, ImageFont, ImageFilter, ImageEnhance# 打开网络图片import requestsfrom io import BytesIOimg = Image.open(BytesIO(requests.get(url).content)).convert('RGB')# 信息print(img.format, img.size, img.mode)# 转换img.convert('L')      # 灰度img.convert('RGB')    # 彩色# 裁剪与旋转img.crop((l, u, r, b))img.rotate(angle, expand=True)# 缩放img.resize((w, h))           # 强制尺寸img.thumbnail((max_w, max_h)) # 保持比例# 滤镜img.filter(ImageFilter.GaussianBlur(radius=5))img.filter(ImageFilter.FIND_EDGES)# 增强ImageEnhance.Brightness(img).enhance(1.5)ImageEnhance.Contrast(img).enhance(2.0)# 绘图draw = ImageDraw.Draw(img)draw.text((x, y), "文字", fill="red", font=font)draw.rectangle([x1, y1, x2, y2], outline="blue", width=3)# 保存img.save("output.jpg", quality=95)

十三、总结

今天我们把 Pillow 的基础操作串成了一条完整的流水线:

  • ✅ 打开 —— Image.open() + convert('RGB')

  • ✅ 读取信息 —— format、size、mode

  • ✅ 格式转换 —— convert() + save()

  • ✅ 裁剪 —— crop((left, upper, right, bottom))

  • ✅ 旋转 —— rotate(angle, expand=True)

  • ✅ 缩放 —— resize() vs thumbnail()

  • ✅ 滤镜 —— ImageFilter 系列

  • ✅ 增强 —— ImageEnhance 系列

  • ✅ 绘图 —— ImageDraw + ImageFont

  • ✅ 流水线 —— 裁 → 缩 → 调 → 印 → 存

关键记忆:Pillow 的日常工作流 = 打开 → 裁剪构图 → 缩放尺寸 → 调色滤镜 → 加水印 → 保存交付。

🎯 今日金句:Pillow 的每个函数都是一颗珠子,单独看平平无奇,但当你把它们串成一条流水线——打开、裁剪、调色、水印、保存——那就是一条能交付价值的项链。

最新文章

随机文章