在日常工作里头, 大家得时常对付好多图片,这些个活儿, 比如把大小统一一下, 弄个水印上去, 再把格式也给变换变换。
手动来进行操作, 既是非常地耗时间, 而且又特别容易把一些东西给漏掉。
今天要教你所使用的关于库的实现方法, 通过这种方式来使得一键式的批量处理操作得以完成。
在第一个场景之中, 大家会去执行一个用来批量修改图片大小的操作。
现在假设有那么一个文件夹, 这里面装了有几百张图片。它们都是用来显示产品的图样。可是这些小图的尺寸并不一样大。所以现在的需求就是要把这些照片的宽高全部调整成标准的八百乘六百像素规格。
from PIL import Imageimport os
def batch_resize(input_folder, output_folder, size=(800, 600)):
"""批量调整图片尺寸"""
# 创建输出文件夹
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 支持的图片格式
supported_formats = ('.jpg', '.jpeg', '.png', '.bmp', '.gif')
for filename in os.listdir(input_folder):
if filename.lower().endswith(supported_formats):
img_path = os.path.join(input_folder, filename)
try:
with Image.open(img_path) as img:
# 保持纵横比的缩放(不拉伸)
img.thumbnail(size, Image.Resampling.LANCZOS)
output_path = os.path.join(output_folder, filename)
img.save(output_path, quality=90)
print(f" 已处理: {filename}")
except Exception as e:
print(f" 处理失败 {filename}: {e}")
# 使用方法
batch_resize('原始图片', '处理后的图片', size=(1024, 768))
第二个情况是关于批量进行格式转换, 也就是把JPG格式的图像转换成PNG格式。
def batch_convert_format(input_folder, output_folder, target_format='PNG'):"""批量转换图片格式"""
if not os.path.exists(output_folder):
os.makedirs(output_folder)
for filename in os.listdir(input_folder):
if filename.lower().endswith(('.jpg', '.jpeg')):
img_path = os.path.join(input_folder, filename)
name_without_ext = os.path.splitext(filename)[0]
with Image.open(img_path) as img:
# JPG没有透明通道,转为PNG前要转换模式
if img.mode == 'RGB':
output_path = os.path.join(output_folder, f"{name_without_ext}.png")
img.save(output_path, format='PNG')
print(f" 已转换: {filename} → {name_without_ext}.png")
batch_convert_format('原始图片', 'PNG图片')
场景三的情况, 是批量添加文字水印。
from PIL import ImageDraw, ImageFontdef batch_add_watermark(input_folder, output_folder, text='© 版权所有'):
"""批量添加文字水印"""
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 加载字体(Windows示例路径,需根据实际情况修改)
try:
font = ImageFont.truetype('C:/Windows/Fonts/msyh.ttc', 30)
except:
font = ImageFont.load_default()
for filename in os.listdir(input_folder):
if filename.lower().endswith(('.jpg', '.png')):
img_path = os.path.join(input_folder, filename)
with Image.open(img_path) as img:
# 转换为RGBA以支持半透明
if img.mode !
= 'RGBA':
img = img.convert('RGBA')
# 创建透明图层
txt_layer = Image.new('RGBA', img.size, (255, 255, 255, 0))
draw = ImageDraw.Draw(txt_layer)
# 计算文字位置(右下角,距边缘20像素)
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
width, height = img.size
x = width - text_width - 20
y = height - text_height - 20
# 绘制半透明白色文字
draw.text((x, y), text, fill=(255, 255, 255, 128), font=font)
# 合成
watermarked = Image.alpha_composite(img, txt_layer)
# 保存
output_path = os.path.join(output_folder, filename)
watermarked.convert('RGB').save(output_path, quality=85)
print(f" 已添加水印: {filename}")
batch_add_watermark('原始图片', '加水印的图片')
完整一键批量处理脚本
import osfrom PIL import Image
def batch_process_images(input_folder, output_folder, target_size=(1024, 768),
target_format='JPEG', watermark_text=None):
"""
万能批量图片处理器
"""
if not os.path.exists(output_folder):
os.makedirs(output_folder)
count = 0
for filename in os.listdir(input_folder):
if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp')):
img_path = os.path.join(input_folder, filename)
name_without_ext = os.path.splitext(filename)[0]
try:
with Image.open(img_path) as img:
# 1. 调整尺寸(保持比例)
img.thumbnail(target_size, Image.Resampling.LANCZOS)
# 2. 添加水印(如果有)
if watermark_text:
draw = ImageDraw.Draw(img)
font = ImageFont.load_default()
draw.text((10, 10), watermark_text, fill='white')
# 3. 保存
output_path = os.path.join(output_folder,
f"{name_without_ext}.{target_format.lower()}")
if target_format.upper() == 'JPEG':
img.convert('RGB').save(output_path, 'JPEG', quality=85)
else:
img.save(output_path)
count += 1
print(f" 进度: {count} - {filename}")
except Exception as e:
print(f" 错误: {filename} - {e}")
print(f"\n 处理完成!
共处理 {count} 张图片")
# 使用示例
batch_process_images('原始图片', '最终图片',
target_size=(1024, 768),
target_format='JPEG',
watermark_text='My Website')
关于内存管理的提醒内容是, 当你对那些体积很大的图片进行批量操作的时候, 必须使用with语句来让系统自动把对应的资源释放掉, 这样才能够避免发生内存泄漏的情况。
你平日里究竟是需要应对和处理哪一种类型的图片工作任务呢? 请在评论区域里头向大家详细地告知一下, 以便我们能够在后续的下一期内容里面去专门地、有针对性地去制作并发布出一期相关的教程来。