第163集:图片批量处理
一、图片批量处理概述
1. 什么是图片批量处理
图片批量处理是指对多张图片同时执行相同或相似的操作,如调整大小、转换格式、添加水印等,以提高工作效率。
2. 应用场景
- 网站图片优化:统一调整图片尺寸和格式
- 摄影后期:批量添加水印、调整色彩
- 文档处理:批量转换图片格式
- 社交媒体:批量制作符合平台要求的图片
3. 常用Python库
- Pillow:Python图像处理标准库,提供丰富的图片操作功能
- OpenCV:主要用于计算机视觉,但也可用于批量图像处理
- imageio:用于读取和写入多种图像数据格式
二、Pillow库安装与基础
1. 安装Pillow
pip install pillow2. 基本图像操作
from PIL import Image
# 打开图片
img = Image.open('example.jpg')
# 查看图片信息
print(f"图片尺寸: {img.size}")
print(f"图片格式: {img.format}")
print(f"图片模式: {img.mode}")
# 显示图片
# img.show()
# 保存图片
img.save('output.jpg')三、图片批量处理核心功能
1. 批量调整图片大小
功能说明:将指定目录下的所有图片调整为统一尺寸
代码实现:
import os
from PIL import Image
def batch_resize_images(input_dir, output_dir, size):
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 获取所有图片文件
image_files = [f for f in os.listdir(input_dir)
if f.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif'))]
# 批量处理图片
for i, filename in enumerate(image_files, 1):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
try:
with Image.open(input_path) as img:
# 调整大小
resized_img = img.resize(size, Image.Resampling.LANCZOS)
# 保存图片
resized_img.save(output_path)
print(f"已处理 {i}/{len(image_files)}: {filename}")
except Exception as e:
print(f"处理 {filename} 时出错: {e}")
# 使用示例
batch_resize_images('images', 'resized_images', (800, 600))2. 批量转换图片格式
功能说明:将指定目录下的所有图片转换为另一种格式(如PNG转JPG)
代码实现:
import os
from PIL import Image
def batch_convert_format(input_dir, output_dir, output_format):
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 获取所有图片文件
image_files = [f for f in os.listdir(input_dir)
if f.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif'))]
# 批量转换格式
for i, filename in enumerate(image_files, 1):
input_path = os.path.join(input_dir, filename)
# 生成新文件名
name, ext = os.path.splitext(filename)
output_path = os.path.join(output_dir, f"{name}.{output_format.lower()}")
try:
with Image.open(input_path) as img:
# 如果是RGBA模式(透明背景)且要转换为JPG,需要先转换为RGB
if img.mode == 'RGBA' and output_format.lower() == 'jpg':
img = img.convert('RGB')
img.save(output_path, output_format.upper())
print(f"已转换 {i}/{len(image_files)}: {filename} → {output_format}")
except Exception as e:
print(f"转换 {filename} 时出错: {e}")
# 使用示例
batch_convert_format('images', 'converted_images', 'jpg')3. 批量添加水印
功能说明:为指定目录下的所有图片添加文字水印
代码实现:
import os
from PIL import Image, ImageDraw, ImageFont
def batch_add_watermark(input_dir, output_dir, watermark_text, font_path=None):
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 获取所有图片文件
image_files = [f for f in os.listdir(input_dir)
if f.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif'))]
# 批量添加水印
for i, filename in enumerate(image_files, 1):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
try:
with Image.open(input_path) as img:
# 创建绘图对象
draw = ImageDraw.Draw(img)
# 设置字体
if font_path:
font = ImageFont.truetype(font_path, 36)
else:
font = ImageFont.load_default()
# 获取水印文本大小
text_width, text_height = draw.textbbox((0, 0), watermark_text, font=font)[2:4]
# 计算水印位置(右下角)
img_width, img_height = img.size
x = img_width - text_width - 20
y = img_height - text_height - 20
# 添加水印
draw.text((x, y), watermark_text, font=font, fill=(255, 255, 255, 128))
# 保存图片
img.save(output_path)
print(f"已添加水印 {i}/{len(image_files)}: {filename}")
except Exception as e:
print(f"添加水印到 {filename} 时出错: {e}")
# 使用示例
batch_add_watermark('images', 'watermarked_images', '© Python教程')4. 批量调整图片质量
功能说明:调整JPEG图片的压缩质量,减小文件大小
代码实现:
import os
from PIL import Image
def batch_adjust_quality(input_dir, output_dir, quality):
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 获取所有JPEG图片文件
image_files = [f for f in os.listdir(input_dir)
if f.lower().endswith(('.jpg', '.jpeg'))]
# 批量调整质量
for i, filename in enumerate(image_files, 1):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
try:
with Image.open(input_path) as img:
# 保存图片并设置质量
img.save(output_path, 'JPEG', quality=quality)
print(f"已调整质量 {i}/{len(image_files)}: {filename}")
except Exception as e:
print(f"调整 {filename} 质量时出错: {e}")
# 使用示例(质量范围:1-100,数字越大质量越高)
batch_adjust_quality('images', 'compressed_images', 85)5. 批量旋转图片
功能说明:将指定目录下的所有图片旋转指定角度
代码实现:
import os
from PIL import Image
def batch_rotate_images(input_dir, output_dir, angle):
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 获取所有图片文件
image_files = [f for f in os.listdir(input_dir)
if f.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif'))]
# 批量旋转图片
for i, filename in enumerate(image_files, 1):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
try:
with Image.open(input_path) as img:
# 旋转图片,expand=True保证完整显示
rotated_img = img.rotate(angle, expand=True)
rotated_img.save(output_path)
print(f"已旋转 {i}/{len(image_files)}: {filename}")
except Exception as e:
print(f"旋转 {filename} 时出错: {e}")
# 使用示例(角度为正表示顺时针旋转)
batch_rotate_images('images', 'rotated_images', 90)三、高级批量图像处理
1. 批量裁剪图片
import os
from PIL import Image
def batch_crop_images(input_dir, output_dir, left, top, right, bottom):
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 获取所有图片文件
image_files = [f for f in os.listdir(input_dir)
if f.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif'))]
# 批量裁剪图片
for i, filename in enumerate(image_files, 1):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
try:
with Image.open(input_path) as img:
# 裁剪图片
cropped_img = img.crop((left, top, right, bottom))
cropped_img.save(output_path)
print(f"已裁剪 {i}/{len(image_files)}: {filename}")
except Exception as e:
print(f"裁剪 {filename} 时出错: {e}")
# 使用示例(裁剪区域:左、上、右、下坐标)
batch_crop_images('images', 'cropped_images', 100, 100, 500, 500)2. 批量转换为黑白图片
import os
from PIL import Image
def batch_convert_to_bw(input_dir, output_dir):
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 获取所有图片文件
image_files = [f for f in os.listdir(input_dir)
if f.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif'))]
# 批量转换为黑白
for i, filename in enumerate(image_files, 1):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
try:
with Image.open(input_path) as img:
# 转换为黑白
bw_img = img.convert('L')
bw_img.save(output_path)
print(f"已转换为黑白 {i}/{len(image_files)}: {filename}")
except Exception as e:
print(f"转换 {filename} 为黑白时出错: {e}")
# 使用示例
batch_convert_to_bw('images', 'bw_images')四、综合案例:图片处理流水线
1. 需求分析
创建一个图片处理流水线,对图片执行以下操作:
- 调整大小为800x600
- 转换为JPG格式
- 添加水印
- 降低质量以减小文件大小
2. 实现代码
import os
from PIL import Image, ImageDraw, ImageFont
def image_processing_pipeline(input_dir, output_dir, watermark_text, quality=85):
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 获取所有图片文件
image_files = [f for f in os.listdir(input_dir)
if f.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif'))]
# 批量处理图片
for i, filename in enumerate(image_files, 1):
input_path = os.path.join(input_dir, filename)
name, _ = os.path.splitext(filename)
output_path = os.path.join(output_dir, f"{name}.jpg")
try:
with Image.open(input_path) as img:
# 1. 调整大小
img = img.resize((800, 600), Image.Resampling.LANCZOS)
# 2. 转换为RGB模式(确保可以保存为JPG)
if img.mode == 'RGBA':
img = img.convert('RGB')
# 3. 添加水印
draw = ImageDraw.Draw(img)
font = ImageFont.load_default()
text_width, text_height = draw.textbbox((0, 0), watermark_text, font=font)[2:4]
img_width, img_height = img.size
x = img_width - text_width - 20
y = img_height - text_height - 20
draw.text((x, y), watermark_text, font=font, fill=(255, 255, 255, 128))
# 4. 降低质量并保存
img.save(output_path, 'JPEG', quality=quality)
print(f"已处理 {i}/{len(image_files)}: {filename}")
except Exception as e:
print(f"处理 {filename} 时出错: {e}")
# 使用示例
image_processing_pipeline('raw_images', 'processed_images', '© Python自动化教程')五、注意事项与最佳实践
1. 注意事项
- 处理前备份原始图片,避免不可逆操作
- 注意图片格式兼容性,如PNG转JPG会丢失透明通道
- 大图片批量处理可能消耗较多内存,可考虑分批处理
2. 最佳实践
- 使用上下文管理器(
with语句)确保图片文件正确关闭 - 添加适当的错误处理,提高脚本的健壮性
- 根据实际需求选择合适的图像处理方法和参数
- 对于大量图片,考虑使用多进程或多线程提高处理速度
六、扩展学习
- 多进程处理:使用
multiprocessing库加速批量处理 - 图像增强:使用Pillow或OpenCV进行批量图像增强
- 人脸识别:结合人脸识别技术进行批量人像处理
- 视频帧处理:将视频拆分为帧进行批量处理,再合成视频
通过本集的学习,你已经掌握了使用Python进行图片批量处理的基本方法和高级技巧。在实际应用中,可以根据具体需求组合这些操作,创建更复杂的图像处理流程。