导航菜单

  • 1.langchain.intro
  • 2.langchain.chat_models
  • 3.langchain.prompts
  • 4.langchain.example_selectors
  • 5.output_parsers
  • 6.Runnable
  • 7.memory
  • 8.document_loaders
  • 9.text_splitters
  • 10.embeddings
  • 11.tool
  • 12.retrievers
  • 13.optimize
  • 14.项目介绍
  • 15.启动HTTP
  • 16.数据与模型
  • 17.权限管理
  • 18.知识库管理
  • 19.设置
  • 20.文档管理
  • 21.聊天
  • 22.API文档
  • 23.RAG优化
  • 24.索引时优化
  • 25.检索前优化
  • 26.检索后优化
  • 27.系统优化
  • 28.GraphRAG
  • 29.图
  • 30.为什么选择图数据库
  • 31.什么是 Neo4j
  • 32.安装和连接 Neo4j
  • 33.Neo4j核心概念
  • 34.Cypher基础
  • 35.模式匹配
  • 36.数据CRUD操作
  • 37.GraphRAG
  • 38.查询和过滤
  • 39.结果处理和聚合
  • 40.语句组合
  • 41.子查询
  • 42.模式和约束
  • 43.日期时间处理
  • 44.Cypher内置函数
  • 45.Python操作Neo4j
  • 46.neo4j
  • 47.py2neo
  • 48.Streamlit
  • 49.Pandas
  • 50.graphRAG
  • 51.deepdoc
  • 52.deepdoc
  • 53.deepdoc
  • 55.deepdoc
  • 54.deepdoc
  • Pillow
  • 1. 什么是 Pillow
  • 2. 安装 Pillow
  • 3. 图像打开与保存
    • 3.1 打开图像
    • 3.2 保存图像
  • 4. 获取图像基本信息
    • 4.1 基本属性
    • 4.2 完整示例
  • 5. 图像基本操作
    • 5.1 调整图片大小
    • 5.2 旋转图片
    • 5.3 翻转图片
  • 6. 图像模式转换
    • 6.1 常见模式转换
  • 7. 图像裁剪与合成
    • 7.1 裁剪图片
    • 7.2 合成图片(粘贴)
  • 8. 滤镜与图像增强
    • 8.1 应用滤镜
    • 8.2 图像增强
  • 9.绘制图形和文字
    • 9.1 绘制图形
    • 9.2 添加文字
  • 10. 批量处理图片
    • 10.1 批量调整大小
    • 10.2 批量格式转换
    • 10.3 完整批量处理示例
  • 11. 实用示例
    • 11.1 添加文字水印
    • 11.2 图片拼接
    • 11.3 创建图片网格
  • 12. 常见问题与最佳实践
    • 12.1 常见问题
    • 12.2 最佳实践

1. 什么是 Pillow #

Pillow 是 Python 中最流行的图像处理库,它是 PIL(Python Imaging Library)的现代维护版本。

为什么选择 Pillow?

  • 功能强大:支持几乎所有常见的图像格式
  • 易于使用:API 简洁直观
  • 广泛应用:在 Web 开发、数据分析、机器学习等领域都有大量使用
  • 性能优秀:底层使用 C 语言实现,处理速度快

Pillow 能做什么?

  • 打开、保存各种格式的图片
  • 调整图片大小、旋转、翻转
  • 裁剪、拼接图片
  • 添加滤镜效果
  • 调整亮度、对比度、饱和度
  • 在图片上绘制图形和文字
  • 批量处理多张图片

2. 安装 Pillow #

在使用 Pillow 之前,需要先安装它。安装方法非常简单:

# 使用 pip 安装(推荐)
pip install Pillow

# 如果使用 conda
conda install pillow

验证安装: 安装完成后,可以在 Python 中导入来验证是否安装成功:

# 导入 Pillow 库
# 注意:虽然安装的是 Pillow,但导入时使用 PIL(保持向后兼容)
from PIL import Image

# 如果导入成功,说明安装正确
print("Pillow 安装成功!")

3. 图像打开与保存 #

打开和保存图像是 Pillow 最基础的操作,也是所有图像处理的第一步。

3.1 打开图像 #

使用 Image.open() 方法可以打开一张图片。这个方法支持多种格式:JPEG、PNG、GIF、BMP、TIFF、WebP 等。

# 导入 Image 模块
from PIL import Image

# 打开一张图片
# 参数:图片文件的路径(可以是相对路径或绝对路径)
img = Image.open('image.jpg')

# 如果图片不存在,会抛出 FileNotFoundError 异常
# 建议使用 try-except 处理异常
try:
    img = Image.open('image.jpg')
    print("图片打开成功!")
except FileNotFoundError:
    print("图片文件不存在!")

注意事项:

  • 文件路径可以是相对路径(相对于当前工作目录)或绝对路径
  • 打开图片后,图片数据并没有完全加载到内存,只有在需要时才会加载
  • 打开后的图片对象可以查看基本信息,但修改操作会创建新的图片对象

3.2 保存图像 #

使用 save() 方法可以保存图片。Pillow 会根据文件扩展名自动选择保存格式。

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('input.jpg')

# 保存图片
# 方法1:使用默认格式(根据扩展名自动判断)
img.save('output.png')  # 保存为 PNG 格式

# 方法2:显式指定格式
img.save('output.png', 'PNG')

# 方法3:保存时指定质量参数(适用于 JPEG)
img.save('output.jpg', 'JPEG', quality=85)  # quality 范围 1-100,数值越大质量越好

# 方法4:保存为 WebP 格式(现代格式,压缩率高)
img.save('output.webp', 'WEBP', quality=85)

完整示例:

# 导入 Image 模块
from PIL import Image

# 打开一张图片
img = Image.open('photo.jpg')

# 保存为不同格式
img.save('photo_copy.jpg')      # 保存为 JPEG
img.save('photo_copy.png')     # 保存为 PNG
img.save('photo_copy.webp')   # 保存为 WebP

print("图片保存完成!")

4. 获取图像基本信息 #

在处理图片之前,通常需要先了解图片的基本信息,比如尺寸、格式、颜色模式等。

4.1 基本属性 #

图片对象有几个常用的属性可以获取基本信息:

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('image.jpg')

# 获取图片格式(如 JPEG、PNG 等)
print("图片格式:", img.format)

# 获取图片尺寸,返回元组 (宽度, 高度)
print("图片尺寸:", img.size)
print("图片宽度:", img.width)
print("图片高度:", img.height)

# 获取图片颜色模式
# 常见模式:RGB(彩色)、RGBA(带透明通道)、L(灰度)、1(黑白)
print("颜色模式:", img.mode)

4.2 完整示例 #

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('image.jpg')

# 打印所有基本信息
print("=" * 40)
print("图片基本信息")
print("=" * 40)
print(f"格式: {img.format}")
print(f"尺寸: {img.size[0]} x {img.size[1]} 像素")
print(f"宽度: {img.width} 像素")
print(f"高度: {img.height} 像素")
print(f"颜色模式: {img.mode}")
print("=" * 40)

颜色模式说明:

  • RGB:红绿蓝三色模式,最常见的彩色图片模式
  • RGBA:在 RGB 基础上增加了透明通道(Alpha),PNG 图片常用
  • L:灰度模式,只有亮度信息,没有颜色信息
  • 1:二值图像,只有黑白两种颜色
  • P:调色板模式,使用颜色索引表

5. 图像基本操作 #

图像的基本操作包括调整大小、旋转、翻转等,这些是最常用的图像处理功能。

5.1 调整图片大小 #

调整图片大小有两种方法:resize() 和 thumbnail()。

方法1:resize() - 可以改变宽高比

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('image.jpg')

# 调整到指定尺寸(宽度, 高度)
# 注意:这会改变图片的宽高比,可能导致图片变形
resized = img.resize((300, 200))
resized.save('resized_300x200.jpg')

# 按比例缩小(缩小到原来的一半)
new_width = img.width // 2
new_height = img.height // 2
resized_half = img.resize((new_width, new_height))
resized_half.save('resized_half.jpg')

print("图片调整完成!")

方法2:thumbnail() - 保持宽高比

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('image.jpg')

# 创建缩略图
# thumbnail() 会保持宽高比,确保图片不会变形
# 参数是最大尺寸,图片会按比例缩小,但不会超过这个尺寸
img.thumbnail((300, 300))  # 最大宽度和高度都是 300 像素

# 注意:thumbnail() 会直接修改原图片对象,不会创建新对象
img.save('thumbnail_300x300.jpg')

print("缩略图创建完成!")

完整示例:

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('photo.jpg')
print(f"原始尺寸: {img.size}")

# 方法1:使用 resize(可能变形)
resized = img.resize((400, 300))
resized.save('resized.jpg')
print(f"resize 后尺寸: {resized.size}")

# 方法2:使用 thumbnail(保持比例)
img_copy = Image.open('photo.jpg')  # 重新打开,因为 thumbnail 会修改原图
img_copy.thumbnail((400, 300))
img_copy.save('thumbnail.jpg')
print(f"thumbnail 后尺寸: {img_copy.size}")

5.2 旋转图片 #

使用 rotate() 方法可以旋转图片:

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('image.jpg')

# 旋转图片
# 参数1:旋转角度(正数逆时针,负数顺时针)
# 参数2:expand=True 表示扩大画布以容纳旋转后的图片,避免被裁剪
rotated_90 = img.rotate(90, expand=True)
rotated_90.save('rotated_90.jpg')

# 旋转 45 度
rotated_45 = img.rotate(45, expand=True)
rotated_45.save('rotated_45.jpg')

# 旋转 -90 度(顺时针 90 度)
rotated_minus_90 = img.rotate(-90, expand=True)
rotated_minus_90.save('rotated_minus_90.jpg')

print("图片旋转完成!")

完整示例:

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('photo.jpg')

# 旋转不同角度
angles = [90, 180, 270]
for angle in angles:
    rotated = img.rotate(angle, expand=True)
    rotated.save(f'rotated_{angle}.jpg')
    print(f"已保存旋转 {angle} 度的图片")

print("所有旋转操作完成!")

5.3 翻转图片 #

使用 transpose() 方法可以翻转图片:

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('image.jpg')

# 水平翻转(左右镜像)
flipped_horizontal = img.transpose(Image.FLIP_LEFT_RIGHT)
flipped_horizontal.save('flipped_horizontal.jpg')

# 垂直翻转(上下镜像)
flipped_vertical = img.transpose(Image.FLIP_TOP_BOTTOM)
flipped_vertical.save('flipped_vertical.jpg')

print("图片翻转完成!")

完整示例:

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('photo.jpg')

# 水平翻转
horizontal = img.transpose(Image.FLIP_LEFT_RIGHT)
horizontal.save('flipped_horizontal.jpg')

# 垂直翻转
vertical = img.transpose(Image.FLIP_TOP_BOTTOM)
vertical.save('flipped_vertical.jpg')

print("翻转操作完成!")

6. 图像模式转换 #

不同的图片有不同的颜色模式,有时需要转换模式以满足处理需求。

6.1 常见模式转换 #

# 导入 Image 模块
from PIL import Image

# 打开彩色图片
img = Image.open('color_image.jpg')
print(f"原始模式: {img.mode}")

# 转换为灰度图
# 'L' 表示灰度模式(Luminance)
gray_img = img.convert('L')
gray_img.save('gray_image.jpg')
print(f"灰度模式: {gray_img.mode}")

# 转换为 RGB 模式(确保是 RGB)
rgb_img = img.convert('RGB')
rgb_img.save('rgb_image.jpg')
print(f"RGB 模式: {rgb_img.mode}")

# 转换为 RGBA 模式(添加透明通道)
rgba_img = img.convert('RGBA')
rgba_img.save('rgba_image.png')  # PNG 支持透明通道
print(f"RGBA 模式: {rgba_img.mode}")

完整示例:

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('photo.jpg')
print(f"原始图片模式: {img.mode}")

# 转换为灰度图
if img.mode != 'L':
    gray = img.convert('L')
    gray.save('photo_gray.jpg')
    print(f"灰度图已保存,模式: {gray.mode}")

# 确保是 RGB 模式
if img.mode != 'RGB':
    rgb = img.convert('RGB')
    rgb.save('photo_rgb.jpg')
    print(f"RGB 图已保存,模式: {rgb.mode}")

模式转换说明:

  • RGB → L(灰度):将彩色图片转为黑白,常用于简化处理
  • 任意模式 → RGB:统一转换为 RGB,确保后续处理兼容
  • RGB → RGBA:添加透明通道,用于需要透明效果的场景

7. 图像裁剪与合成 #

裁剪可以提取图片的某个区域,合成可以将多张图片组合在一起。

7.1 裁剪图片 #

使用 crop() 方法可以裁剪图片的指定区域:

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('image.jpg')
print(f"原始尺寸: {img.size}")

# 裁剪图片
# crop() 的参数是一个元组:(左, 上, 右, 下)
# 坐标系统:左上角为 (0, 0),向右为 x 轴正方向,向下为 y 轴正方向
# 例如:(100, 100, 400, 400) 表示从 (100, 100) 到 (400, 400) 的矩形区域
box = (100, 100, 400, 400)
cropped = img.crop(box)
cropped.save('cropped.jpg')
print(f"裁剪后尺寸: {cropped.size}")

# 裁剪图片中心区域
width, height = img.size
# 计算中心区域的坐标
left = width // 4
top = height // 4
right = width * 3 // 4
bottom = height * 3 // 4
center_box = (left, top, right, bottom)
center_cropped = img.crop(center_box)
center_cropped.save('center_cropped.jpg')

print("裁剪完成!")

完整示例:

# 导入 Image 模块
from PIL import Image

# 打开图片
img = Image.open('photo.jpg')
width, height = img.size
print(f"原始图片尺寸: {width} x {height}")

# 裁剪左上角 1/4 区域
box1 = (0, 0, width // 2, height // 2)
cropped1 = img.crop(box1)
cropped1.save('cropped_top_left.jpg')
print(f"左上角区域: {cropped1.size}")

# 裁剪中心区域
left = width // 4
top = height // 4
right = width * 3 // 4
bottom = height * 3 // 4
box2 = (left, top, right, bottom)
cropped2 = img.crop(box2)
cropped2.save('cropped_center.jpg')
print(f"中心区域: {cropped2.size}")

7.2 合成图片(粘贴) #

使用 paste() 方法可以将一张图片粘贴到另一张图片上:

# 导入 Image 模块
from PIL import Image

# 打开主图片
main_img = Image.open('background.jpg')

# 打开要粘贴的图片(如 logo)
logo = Image.open('logo.png')

# 调整 logo 大小(可选)
logo.thumbnail((100, 100))

# 粘贴图片
# 参数1:要粘贴的图片
# 参数2:粘贴位置的坐标 (x, y),左上角为 (0, 0)
main_img.paste(logo, (50, 50))

# 保存结果
main_img.save('pasted.jpg')

print("图片粘贴完成!")

完整示例:

# 导入 Image 模块
from PIL import Image

# 打开背景图片
background = Image.open('background.jpg')
print(f"背景图片尺寸: {background.size}")

# 打开要粘贴的图片
overlay = Image.open('logo.png')
print(f"原 logo 尺寸: {overlay.size}")

# 调整 logo 大小
overlay.thumbnail((200, 200))
print(f"调整后 logo 尺寸: {overlay.size}")

# 粘贴到不同位置
# 左上角
background_copy1 = background.copy()
background_copy1.paste(overlay, (10, 10))
background_copy1.save('pasted_top_left.jpg')

# 右下角
background_copy2 = background.copy()
x = background.width - overlay.width - 10
y = background.height - overlay.height - 10
background_copy2.paste(overlay, (x, y))
background_copy2.save('pasted_bottom_right.jpg')

print("粘贴操作完成!")

8. 滤镜与图像增强 #

Pillow 提供了丰富的滤镜效果和图像增强功能,可以让图片看起来更好。

8.1 应用滤镜 #

使用 ImageFilter 模块可以应用各种滤镜效果:

# 导入需要的模块
from PIL import Image, ImageFilter

# 打开图片
img = Image.open('image.jpg')

# 模糊效果
blurred = img.filter(ImageFilter.BLUR)
blurred.save('blurred.jpg')

# 锐化效果
sharpened = img.filter(ImageFilter.SHARPEN)
sharpened.save('sharpened.jpg')

# 边缘检测
edges = img.filter(ImageFilter.FIND_EDGES)
edges.save('edges.jpg')

# 轮廓效果
contour = img.filter(ImageFilter.CONTOUR)
contour.save('contour.jpg')

# 浮雕效果
emboss = img.filter(ImageFilter.EMBOSS)
emboss.save('emboss.jpg')

print("滤镜应用完成!")

完整示例:

# 导入需要的模块
from PIL import Image, ImageFilter

# 打开图片
img = Image.open('photo.jpg')

# 定义要应用的滤镜
filters = {
    'blur': ImageFilter.BLUR,
    'sharpen': ImageFilter.SHARPEN,
    'edges': ImageFilter.FIND_EDGES,
    'contour': ImageFilter.CONTOUR,
    'emboss': ImageFilter.EMBOSS,
}

# 应用每个滤镜并保存
for name, filter_type in filters.items():
    filtered = img.filter(filter_type)
    filtered.save(f'filtered_{name}.jpg')
    print(f"已保存 {name} 滤镜效果")

print("所有滤镜应用完成!")

8.2 图像增强 #

使用 ImageEnhance 模块可以调整图片的亮度、对比度、饱和度等:

# 导入需要的模块
from PIL import Image, ImageEnhance

# 打开图片
img = Image.open('image.jpg')

# 调整亮度
# 创建亮度增强器
brightness_enhancer = ImageEnhance.Brightness(img)
# enhance() 参数:1.0 为原始亮度,>1.0 更亮,<1.0 更暗
bright_img = brightness_enhancer.enhance(1.5)  # 提高 50% 亮度
bright_img.save('bright.jpg')

# 调整对比度
contrast_enhancer = ImageEnhance.Contrast(img)
# enhance() 参数:1.0 为原始对比度,>1.0 对比度更高,<1.0 对比度更低
high_contrast = contrast_enhancer.enhance(2.0)  # 对比度加倍
high_contrast.save('high_contrast.jpg')

# 调整色彩饱和度
color_enhancer = ImageEnhance.Color(img)
# enhance() 参数:1.0 为原始饱和度,>1.0 更鲜艳,<1.0 更灰暗
vibrant = color_enhancer.enhance(1.5)  # 饱和度提高 50%
vibrant.save('vibrant.jpg')

# 调整清晰度
sharpness_enhancer = ImageEnhance.Sharpness(img)
# enhance() 参数:1.0 为原始清晰度,>1.0 更清晰,<1.0 更模糊
sharp = sharpness_enhancer.enhance(2.0)  # 清晰度加倍
sharp.save('sharp.jpg')

print("图像增强完成!")

完整示例:

# 导入需要的模块
from PIL import Image, ImageEnhance

# 打开图片
img = Image.open('photo.jpg')

# 调整亮度
brightness = ImageEnhance.Brightness(img)
bright = brightness.enhance(1.3)  # 提高 30% 亮度
bright.save('enhanced_bright.jpg')

# 调整对比度
contrast = ImageEnhance.Contrast(img)
high_contrast = contrast.enhance(1.5)  # 提高 50% 对比度
high_contrast.save('enhanced_contrast.jpg')

# 调整饱和度
color = ImageEnhance.Color(img)
vibrant = color.enhance(1.4)  # 提高 40% 饱和度
vibrant.save('enhanced_color.jpg')

print("所有增强操作完成!")

9.绘制图形和文字 #

Pillow 可以在图片上绘制图形和文字,这对于添加水印、标注等非常有用。

9.1 绘制图形 #

使用 ImageDraw 模块可以在图片上绘制各种图形:

# 导入需要的模块
from PIL import Image, ImageDraw

# 打开图片或创建新图片
img = Image.open('image.jpg')

# 创建绘制对象
draw = ImageDraw.Draw(img)

# 绘制矩形
# 参数:[(左上角x, 左上角y), (右下角x, 右下角y)], fill=填充颜色, outline=边框颜色
draw.rectangle([(100, 100), (200, 200)], fill='red', outline='blue', width=3)

# 绘制椭圆(圆形)
# 参数:[(左上角x, 左上角y), (右下角x, 右下角y)], fill=填充颜色
draw.ellipse([(150, 150), (250, 250)], fill='green', outline='black', width=2)

# 绘制直线
# 参数:[(起点x, 起点y), (终点x, 终点y)], fill=颜色, width=线宽
draw.line([(0, 0), (100, 100)], fill='yellow', width=5)

# 保存图片
img.save('drawn.jpg')

print("图形绘制完成!")

完整示例:

# 导入需要的模块
from PIL import Image, ImageDraw

# 创建一个新的图片(白色背景)
img = Image.new('RGB', (500, 500), color='white')

# 创建绘制对象
draw = ImageDraw.Draw(img)

# 绘制矩形
draw.rectangle([(50, 50), (200, 150)], fill='red', outline='blue', width=3)

# 绘制圆形
draw.ellipse([(250, 50), (400, 200)], fill='green', outline='black', width=2)

# 绘制直线
draw.line([(50, 250), (450, 250)], fill='blue', width=5)

# 绘制多条线(折线)
points = [(100, 300), (200, 350), (300, 320), (400, 380)]
draw.line(points, fill='purple', width=3)

# 保存图片
img.save('drawn_shapes.jpg')
print("图形绘制完成!")

9.2 添加文字 #

使用 ImageDraw 和 ImageFont 可以在图片上添加文字:

# 导入需要的模块
from PIL import Image, ImageDraw, ImageFont

# 打开图片
img = Image.open('image.jpg')

# 创建绘制对象
draw = ImageDraw.Draw(img)

# 设置字体
# 方法1:使用系统字体(如果可用)
try:
    # 尝试加载 TrueType 字体
    font = ImageFont.truetype('arial.ttf', size=40)
except:
    # 如果失败,使用默认字体
    font = ImageFont.load_default()

# 添加文字
# 参数:位置坐标 (x, y), 文字内容, fill=文字颜色, font=字体对象
draw.text((50, 50), "Hello Pillow", fill='white', font=font)

# 保存图片
img.save('text_added.jpg')

print("文字添加完成!")

完整示例:

# 导入需要的模块
from PIL import Image, ImageDraw, ImageFont

# 打开图片
img = Image.open('photo.jpg')

# 创建绘制对象
draw = ImageDraw.Draw(img)

# 尝试加载字体,失败则使用默认字体
try:
    # Windows 系统常见字体路径
    font = ImageFont.truetype('C:/Windows/Fonts/arial.ttf', size=50)
except:
    try:
        # Linux 系统常见字体路径
        font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', size=50)
    except:
        # 使用默认字体
        font = ImageFont.load_default()
        print("使用默认字体")

# 添加文字
text = "Hello Pillow!"
# 计算文字位置(居中)
# 注意:textsize 方法在某些版本中可能不同,这里使用简化方式
text_x = 50
text_y = 50
draw.text((text_x, text_y), text, fill='white', font=font)

# 添加带背景的文字(绘制矩形背景)
text_bbox = draw.textbbox((text_x, text_y), text, font=font)
draw.rectangle(text_bbox, fill='black')
draw.text((text_x, text_y), text, fill='white', font=font)

# 保存图片
img.save('text_added.jpg')
print("文字添加完成!")

10. 批量处理图片 #

在实际应用中,经常需要批量处理多张图片,比如批量调整大小、批量转换格式等。

10.1 批量调整大小 #

# 导入需要的模块
import os
from PIL import Image

# 设置输入和输出文件夹
input_folder = 'input_images/'  # 输入文件夹
output_folder = 'output_images/'  # 输出文件夹

# 创建输出文件夹(如果不存在)
os.makedirs(output_folder, exist_ok=True)

# 遍历输入文件夹中的所有文件
for filename in os.listdir(input_folder):
    # 检查文件扩展名,只处理图片文件
    if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.bmp')):
        # 构建完整的文件路径
        input_path = os.path.join(input_folder, filename)

        # 打开图片
        img = Image.open(input_path)

        # 创建缩略图(保持宽高比)
        img.thumbnail((800, 800))

        # 构建输出文件路径
        output_path = os.path.join(output_folder, filename)

        # 保存处理后的图片
        img.save(output_path)

        print(f"已处理: {filename}")

print("批量处理完成!")

10.2 批量格式转换 #

# 导入需要的模块
import os
from PIL import Image

# 设置输入和输出文件夹
input_folder = 'input_images/'
output_folder = 'output_images/'

# 创建输出文件夹
os.makedirs(output_folder, exist_ok=True)

# 目标格式
target_format = 'PNG'  # 可以改为 'JPEG', 'WEBP' 等

# 遍历输入文件夹
for filename in os.listdir(input_folder):
    if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif')):
        # 打开图片
        input_path = os.path.join(input_folder, filename)
        img = Image.open(input_path)

        # 转换为 RGB 模式(某些格式需要)
        if img.mode != 'RGB' and target_format == 'JPEG':
            img = img.convert('RGB')

        # 构建输出文件名(改变扩展名)
        name_without_ext = os.path.splitext(filename)[0]
        output_filename = f"{name_without_ext}.{target_format.lower()}"
        output_path = os.path.join(output_folder, output_filename)

        # 保存为指定格式
        img.save(output_path, target_format)

        print(f"已转换: {filename} -> {output_filename}")

print("批量转换完成!")

10.3 完整批量处理示例 #

# 导入需要的模块
import os
from PIL import Image

def batch_process_images(input_folder, output_folder, max_size=(800, 800)):
    """
    批量处理图片:调整大小并转换为统一格式

    参数:
        input_folder: 输入文件夹路径
        output_folder: 输出文件夹路径
        max_size: 最大尺寸元组 (宽度, 高度)
    """
    # 创建输出文件夹
    os.makedirs(output_folder, exist_ok=True)

    # 支持的图片格式
    supported_formats = ('.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp')

    # 统计信息
    processed_count = 0
    error_count = 0

    # 遍历输入文件夹
    for filename in os.listdir(input_folder):
        # 检查文件格式
        if not filename.lower().endswith(supported_formats):
            continue

        try:
            # 构建文件路径
            input_path = os.path.join(input_folder, filename)

            # 打开图片
            img = Image.open(input_path)

            # 转换为 RGB 模式(统一格式)
            if img.mode != 'RGB':
                img = img.convert('RGB')

            # 创建缩略图
            img.thumbnail(max_size, Image.Resampling.LANCZOS)

            # 构建输出文件名(统一为 .jpg)
            name_without_ext = os.path.splitext(filename)[0]
            output_filename = f"{name_without_ext}.jpg"
            output_path = os.path.join(output_folder, output_filename)

            # 保存图片
            img.save(output_path, 'JPEG', quality=85)

            processed_count += 1
            print(f"✓ 已处理: {filename}")

        except Exception as e:
            error_count += 1
            print(f"✗ 处理失败: {filename} - {str(e)}")

    # 打印统计信息
    print("\n" + "=" * 40)
    print(f"处理完成!")
    print(f"成功: {processed_count} 张")
    print(f"失败: {error_count} 张")
    print("=" * 40)

# 使用示例
if __name__ == '__main__':
    batch_process_images('input_images/', 'output_images/', max_size=(800, 800))

11. 实用示例 #

下面是一些实际应用中常用的示例。

11.1 添加文字水印 #

# 导入需要的模块
from PIL import Image, ImageDraw, ImageFont

def add_text_watermark(input_path, output_path, watermark_text, position='center'):
    """
    给图片添加文字水印

    参数:
        input_path: 输入图片路径
        output_path: 输出图片路径
        watermark_text: 水印文字
        position: 水印位置 ('center', 'bottom_right', 'top_left' 等)
    """
    # 打开原图
    img = Image.open(input_path).convert('RGBA')

    # 创建文字图层
    txt_layer = Image.new('RGBA', img.size, (255, 255, 255, 0))
    draw = ImageDraw.Draw(txt_layer)

    # 设置字体
    try:
        font = ImageFont.truetype('arial.ttf', 40)
    except:
        font = ImageFont.load_default()

    # 获取文字尺寸
    bbox = draw.textbbox((0, 0), watermark_text, font=font)
    text_width = bbox[2] - bbox[0]
    text_height = bbox[3] - bbox[1]

    # 计算文字位置
    if position == 'center':
        x = (img.width - text_width) // 2
        y = (img.height - text_height) // 2
    elif position == 'bottom_right':
        x = img.width - text_width - 20
        y = img.height - text_height - 20
    elif position == 'top_left':
        x = 20
        y = 20
    else:
        x = 20
        y = 20

    # 绘制半透明文字
    draw.text((x, y), watermark_text, font=font, 
              fill=(255, 255, 255, 128))  # 白色,50% 透明度

    # 合并图层
    watermarked = Image.alpha_composite(img, txt_layer)

    # 保存(转换为 RGB 模式)
    watermarked.convert('RGB').save(output_path, 'JPEG', quality=95)

    print(f"水印添加完成: {output_path}")

# 使用示例
add_text_watermark('photo.jpg', 'watermarked.jpg', 'My Watermark', position='bottom_right')

11.2 图片拼接 #

# 导入需要的模块
from PIL import Image

def concat_images_horizontally(image_paths, output_path):
    """
    水平拼接多张图片

    参数:
        image_paths: 图片路径列表
        output_path: 输出图片路径
    """
    # 打开所有图片
    images = [Image.open(path) for path in image_paths]

    # 获取所有图片的宽度和高度
    widths = [img.width for img in images]
    heights = [img.height for img in images]

    # 计算总宽度和最大高度
    total_width = sum(widths)
    max_height = max(heights)

    # 创建新图片(白色背景)
    new_img = Image.new('RGB', (total_width, max_height), 'white')

    # 依次粘贴图片
    x_offset = 0
    for img in images:
        # 如果图片高度小于最大高度,居中粘贴
        y_offset = (max_height - img.height) // 2
        new_img.paste(img, (x_offset, y_offset))
        x_offset += img.width

    # 保存
    new_img.save(output_path)
    print(f"图片拼接完成: {output_path}")

# 使用示例
image_list = ['image1.jpg', 'image2.jpg', 'image3.jpg']
concat_images_horizontally(image_list, 'concatenated.jpg')

11.3 创建图片网格 #

# 导入需要的模块
from PIL import Image
import os

def create_image_grid(image_folder, output_path, grid_size=(3, 3), thumb_size=(200, 200)):
    """
    创建图片网格(缩略图墙)

    参数:
        image_folder: 图片文件夹路径
        output_path: 输出图片路径
        grid_size: 网格大小 (列数, 行数)
        thumb_size: 每个缩略图的大小
    """
    # 获取所有图片文件
    image_files = [f for f in os.listdir(image_folder) 
                   if f.lower().endswith(('.jpg', '.jpeg', '.png', '.gif'))]

    # 限制图片数量
    max_images = grid_size[0] * grid_size[1]
    image_files = image_files[:max_images]

    # 加载并创建缩略图
    thumbnails = []
    for filename in image_files:
        img_path = os.path.join(image_folder, filename)
        img = Image.open(img_path)
        img.thumbnail(thumb_size)
        thumbnails.append(img)

    # 计算网格尺寸
    grid_width = grid_size[0] * thumb_size[0]
    grid_height = grid_size[1] * thumb_size[1]

    # 创建画布
    grid_img = Image.new('RGB', (grid_width, grid_height), 'white')

    # 粘贴缩略图
    for i, thumb in enumerate(thumbnails):
        # 计算位置
        col = i % grid_size[0]
        row = i // grid_size[0]
        x = col * thumb_size[0]
        y = row * thumb_size[1]

        # 居中粘贴
        x_offset = x + (thumb_size[0] - thumb.width) // 2
        y_offset = y + (thumb_size[1] - thumb.height) // 2
        grid_img.paste(thumb, (x_offset, y_offset))

    # 保存
    grid_img.save(output_path)
    print(f"图片网格创建完成: {output_path}")

# 使用示例
create_image_grid('images/', 'grid.jpg', grid_size=(4, 4), thumb_size=(150, 150))

12. 常见问题与最佳实践 #

12.1 常见问题 #

问题1:图片文件不存在

# 导入需要的模块
from PIL import Image
import os

# 检查文件是否存在
image_path = 'image.jpg'
if os.path.exists(image_path):
    img = Image.open(image_path)
    print("图片打开成功")
else:
    print(f"错误:文件 {image_path} 不存在")

问题2:保存时格式不支持

# 导入需要的模块
from PIL import Image

img = Image.open('image.jpg')

# 显式指定格式
try:
    img.save('output.webp', 'WEBP')
    print("保存成功")
except Exception as e:
    print(f"保存失败: {e}")
    # 如果 WebP 不支持,保存为 PNG
    img.save('output.png', 'PNG')

问题3:处理大图片内存不足

# 导入需要的模块
from PIL import Image

# 打开大图片时使用 with 语句
with Image.open('large_image.jpg') as img:
    # 先缩小再处理
    img.thumbnail((2000, 2000))
    # 进行其他处理
    img.save('processed.jpg')

12.2 最佳实践 #

  1. 使用 with 语句管理资源
# 导入需要的模块
from PIL import Image

# 推荐:使用 with 语句
with Image.open('image.jpg') as img:
    img.thumbnail((800, 800))
    img.save('thumbnail.jpg')
# 图片资源会自动释放
  1. 处理前检查图片信息
# 导入需要的模块
from PIL import Image

img = Image.open('image.jpg')

# 检查图片信息
print(f"格式: {img.format}")
print(f"尺寸: {img.size}")
print(f"模式: {img.mode}")

# 根据信息决定处理方式
if img.mode != 'RGB':
    img = img.convert('RGB')
  1. 批量处理时添加错误处理
# 导入需要的模块
import os
from PIL import Image

for filename in os.listdir('images/'):
    try:
        img = Image.open(f'images/{filename}')
        img.thumbnail((800, 800))
        img.save(f'output/{filename}')
        print(f"✓ {filename}")
    except Exception as e:
        print(f"✗ {filename}: {e}")
  1. 保存 JPEG 时指定质量
# 导入需要的模块
from PIL import Image

img = Image.open('image.png')

# 保存 JPEG 时指定质量(1-100,推荐 85-95)
img.save('output.jpg', 'JPEG', quality=90)
  1. 使用 thumbnail 保持宽高比
# 导入需要的模块
from PIL import Image

img = Image.open('image.jpg')

# 推荐:使用 thumbnail 保持宽高比
img.thumbnail((800, 600))  # 不会变形
img.save('thumbnail.jpg')

# 不推荐:使用 resize 可能变形
# resized = img.resize((800, 600))  # 可能变形
← 上一节 55.deepdoc
下一节 没有下一节 →

访问验证

请输入访问令牌

Token不正确,请重新输入