1. 图像批处理自动化
图像批处理可以对大量文件执行相同的操作,节省了时间和精力。例如,如果你有一个图片文件夹,需要更改它们的大小或添加水印,Pillow 可以帮助你编写一个脚本,将这些操作应用于所有图片。
更改文件夹中所有图片的大小
以下是一个示例,我们将更改文件夹 input_images
中所有图片的大小,并将结果保存到文件夹 output_images
中。
import os
from PIL import Image
input_folder = "input_images/"
output_folder = "output_images/"
new_size = (800, 800)
# 确保用于保存图片的文件夹存在
os.makedirs(output_folder, exist_ok=True)
# 遍历 input_folder 中的每个文件
for filename in os.listdir(input_folder):
if filename.endswith((".jpg", ".jpeg", ".png")):
image_path = os.path.join(input_folder, filename)
# 打开图片并更改大小
with Image.open(image_path) as img:
resized_img = img.resize(new_size)
output_path = os.path.join(output_folder, filename)
# 保存图片
resized_img.save(output_path)
print(f"图片 {filename} 已成功更改大小并保存。")
这个脚本会:
- 从文件夹
input_images
加载所有文件。 - 将每张图片大小更改为 800x800 像素。
- 将修改后的图片保存到文件夹
output_images
。
给图片添加水印
可以很容易地对文件夹中所有图片添加水印。在这个示例中,我们将一个文字水印添加到每张图片的右下角。
from PIL import ImageDraw, ImageFont
input_folder = "input_images/"
output_folder = "watermarked_images/"
watermark_text = "© My Company"
# 确保用于保存图片的文件夹存在
os.makedirs(output_folder, exist_ok=True)
for filename in os.listdir(input_folder):
if filename.endswith((".jpg", ".jpeg", ".png")):
image_path = os.path.join(input_folder, filename)
# 打开图片并创建绘图对象
with Image.open(image_path) as img:
draw = ImageDraw.Draw(img)
width, height = img.size
font = ImageFont.truetype("arial.ttf", 24)
# 水印位置
text_width, text_height = draw.textsize(watermark_text, font=font)
x = width - text_width - 10
y = height - text_height - 10
# 添加水印
draw.text((x, y), watermark_text, font=font, fill=(255, 255, 255, 128))
output_path = os.path.join(output_folder, filename)
img.save(output_path)
print(f"已向图片 {filename} 添加水印。")
这个脚本会:
- 从文件夹
input_images
加载所有图片。 - 在图片的右下角添加文字水印。
- 将结果保存到
watermarked_images
文件夹。
将图片转换为 PNG 格式
也可以很容易地将所有图片转换为同一种格式。在这个示例中,我们将文件夹中的所有图片转换为 PNG 格式。
input_folder = "input_images/"
output_folder = "png_images/"
# 确保用于保存图片的文件夹存在
os.makedirs(output_folder, exist_ok=True)
for filename in os.listdir(input_folder):
if filename.endswith((".jpg", ".jpeg", ".bmp", ".tiff")):
image_path = os.path.join(input_folder, filename)
# 打开并转换图片为 PNG
with Image.open(image_path) as img:
base_filename = os.path.splitext(filename)[0]
output_path = os.path.join(output_folder, f"{base_filename}.png")
img.save(output_path, "PNG")
print(f"图片 {filename} 已成功转换为 PNG。")
此脚本将 JPEG、BMP 和 TIFF 格式的图片转换为 PNG 并保存到 png_images
文件夹中。
2. 操作 GIF 动画
GIF 动画是一系列按顺序显示的图片,创建出运动效果。使用 Pillow,可以创建和编辑 GIF 动画,添加和更改帧,以及控制动画播放速度。
创建简单的 GIF 动画
要生成 GIF 动画,需要准备几张图片(帧),它们会按顺序显示。在这个示例中,我们从文件夹 frames
中的图片创建动画。
# 动画帧图片列表
frames_folder = "frames/"
frames = []
for filename in sorted(os.listdir(frames_folder)):
if filename.endswith((".png", ".jpg")):
frame_path = os.path.join(frames_folder, filename)
frame = Image.open(frame_path)
frames.append(frame)
# 保存帧为 GIF 动画
frames[0].save("animation.gif", save_all=True, append_images=frames[1:], duration=100, loop=0)
这个代码会:
- 从文件夹
frames
中加载图片并添加到frames
列表中。 - 将这些帧制作成 GIF 动画。
- 参数
duration=100
指定每帧的显示时间(毫秒),loop=0
指定动画无限循环。
修改 GIF 动画的播放速度
要改变动画的速度,只需要修改 duration
参数。
# 创建加速动画
frames[0].save("fast_animation.gif", save_all=True, append_images=frames[1:], duration=50, loop=0)
在这个示例中,duration=50
,将 GIF 播放速度加快了两倍。
向现有 GIF 添加新帧
你还可以打开现有的 GIF,添加新帧并保存更新后的动画。
# 打开现有 GIF
with Image.open("existing_animation.gif") as gif:
frames = [frame.copy() for frame in ImageSequence.Iterator(gif)]
# 添加新帧
new_frame = Image.open("new_frame.png")
frames.append(new_frame)
# 保存更新后的动画
frames[0].save("updated_animation.gif", save_all=True, append_images=frames[1:], duration=100, loop=0)
这个代码会将新帧 new_frame.png
添加到动画的结尾。
从 GIF 动画中提取帧
有时需要将 GIF 动画拆分为单独的帧。Pillow 可以提取并单独保存每个帧。
from PIL import ImageSequence
# 打开 GIF 动画并提取帧
with Image.open("animation.gif") as gif:
for i, frame in enumerate(ImageSequence.Iterator(gif)):
frame.save(f"frame_{i}.png")
这个代码将动画中的每帧保存为一个单独的 PNG 图片。
批处理与 GIF 动画的完整示例
最后,我们提供一个示例,结合批量处理和 GIF 操作。我们从文件夹中所有图片创建动画,同时在添加每帧之前修改其大小。
# 加载图片,调整大小并创建 GIF
input_folder = "input_images/"
frames = []
new_size = (400, 400)
for filename in sorted(os.listdir(input_folder)):
if filename.endswith((".jpg", ".jpeg", ".png")):
image_path = os.path.join(input_folder, filename)
with Image.open(image_path) as img:
resized_frame = img.resize(new_size)
frames.append(resized_frame)
GO TO FULL VERSION