0%

python实用项目(1)-使用python批量修改照片分辨率

项目需求:

使用python遍历某个文件夹及子文件夹下所有照片,并将分辨率大于设定像素的照片找出来处理成设定的像素大小,并将处理好的图片放到设定的文件夹下,并且图片的目录结构要和之前一致

项目实现

需要用到Pillow,Pillow 是 Python 中最流行的图像处理库之一,它是 PIL(Python Imaging Library) 的现代分支,支持多种图像格式的打开、编辑和保存。它广泛应用于图像处理、自动化批处理、网页开发(如缩略图生成)等领域。

1. Pillow 的主要功能

  • 打开/保存多种图像格式(JPEG、PNG、GIF、BMP、TIFF 等)
  • 基本图像操作(裁剪、旋转、缩放、翻转)
  • 图像增强(调整亮度、对比度、锐化、模糊)
  • 绘制图形和文字(可用于生成水印或标注)
  • 颜色处理(RGB 转换、滤镜应用)
  • 支持图像序列(GIF/WebP 动画)

    2. 安装 Pillow

    使用 pip 安装:
1
pip install pillow

3. 基本使用方法

(1) 打开和显示图片

1
2
3
4
5
6
7
8
9
10
11
12
from PIL import Image

# 打开图片
img = Image.open("example.jpg")

# 显示图片(调用系统默认图片查看器)
img.show()

# 获取图片信息
print(img.format) # 格式(JPEG, PNG...)
print(img.size) # 尺寸(宽, 高)
print(img.mode) # 颜色模式(RGB, L(灰度)...)

(2) 保存图片

1
img.save("output.png")  # 可自动转换格式

(3) 调整图片大小

1
2
3
4
5
6
7
# 调整尺寸
resized_img = img.resize((300, 200)) # (宽度, 高度)
resized_img.save("resized.jpg")

# 生成缩略图(保持比例)
img.thumbnail((100, 100)) # 最大宽度或高度不超过 100
img.save("thumbnail.jpg")

(4) 旋转和翻转

1
2
3
4
5
6
7
# 旋转 90 度
rotated = img.rotate(90)
rotated.save("rotated.jpg")

# 水平翻转
flipped = img.transpose(Image.FLIP_LEFT_RIGHT)
flipped.save("flipped.jpg")

(5) 裁剪图片

1
2
3
# (left, top, right, bottom)
cropped = img.crop((100, 100, 400, 400)) # 从 (100,100) 到 (400,400)
cropped.save("cropped.jpg")

(6) 添加文字(水印)

1
2
3
4
5
6
from PIL import ImageDraw, ImageFont

draw = ImageDraw.Draw(img)
font = ImageFont.truetype("arial.ttf", 30) # 字体和大小
draw.text((10, 10), "Watermark", fill="red", font=font)
img.save("watermarked.jpg")

(7) 应用滤镜(模糊、锐化等)

1
2
3
4
5
6
7
8
9
from PIL import ImageFilter

# 高斯模糊
blurred = img.filter(ImageFilter.GaussianBlur(5))
blurred.save("blurred.jpg")

# 边缘增强
sharpened = img.filter(ImageFilter.SHARPEN)
sharpened.save("sharpened.jpg")

(8) 转换颜色模式

1
2
3
# 转为灰度图
gray_img = img.convert("L")
gray_img.save("gray.jpg")

4. 进阶用法

(1) 批量处理图片

1
2
3
4
5
6
7
8
9
10
11
12
13
import os
from PIL import Image

input_dir = "input_images/"
output_dir = "output_images/"

os.makedirs(output_dir, exist_ok=True)

for filename in os.listdir(input_dir):
if filename.endswith((".jpg", ".png")):
img = Image.open(os.path.join(input_dir, filename))
img.thumbnail((500, 500))
img.save(os.path.join(output_dir, filename))

(2) 制作 GIF 动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from PIL import Image

# 准备多张图片
frames = []
for i in range(1, 5):
frame = Image.open(f"frame_{i}.png")
frames.append(frame)

# 保存为 GIF
frames[0].save(
"animation.gif",
save_all=True,
append_images=frames[1:],
duration=200, # 每帧延迟(毫秒)
loop=0, # 0=无限循环
)

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import os
from PIL import Image

def get_resolution_input(prompt):
"""获取用户输入的分辨率,格式为'宽 高'"""
while True:
try:
res_input = input(prompt).strip()
width, height = map(int, res_input.split())
if width <= 0 or height <= 0:
print("分辨率必须为正整数,请重新输入")
continue
return width, height
except ValueError:
print("输入格式错误,请按'宽 高'格式输入(例如:480 640)")

def needs_resize(img, max_width, max_height):
"""检查图片是否需要调整大小"""
return img.width > max_width or img.height > max_height

def process_images(input_folder, output_folder, max_width, max_height, copy_untouched):
"""处理图片主函数"""
os.makedirs(output_folder, exist_ok=True)
failed_files = []
processed_count = 0
copied_count = 0
skipped_count = 0

for root, _, files in os.walk(input_folder):
for file in files:
if not file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif', '.webp')):
continue

input_path = os.path.join(root, file)
rel_path = os.path.relpath(root, input_folder)
output_dir = os.path.join(output_folder, rel_path)
output_path = os.path.join(output_dir, file)

try:
with Image.open(input_path) as img:
if needs_resize(img, max_width, max_height):
# 调整图片大小
ratio = min(max_width / img.width, max_height / img.height)
new_size = (int(img.width * ratio), int(img.height * ratio))
resized_img = img.resize(new_size, Image.LANCZOS)

os.makedirs(output_dir, exist_ok=True)
resized_img.save(output_path)
processed_count += 1
print(f"[处理] {input_path} -> {output_path}")
elif copy_untouched:
# 复制未处理的图片
os.makedirs(output_dir, exist_ok=True)
img.save(output_path)
copied_count += 1
print(f"[复制] {input_path} -> {output_path}")
else:
skipped_count += 1
print(f"[跳过] {input_path} (无需调整)")
except Exception as e:
failed_files.append(input_path)
print(f"[失败] {input_path} - 错误: {str(e)}")

# 输出统计信息
print("\n=== 处理结果 ===")
print(f"目标分辨率: {max_width}×{max_height}")
print(f"已处理图片数量: {processed_count}")
if copy_untouched:
print(f"已复制未处理图片数量: {copied_count}")
print(f"跳过图片数量: {skipped_count}")
print(f"失败图片数量: {len(failed_files)}")

if failed_files:
print("\n=== 处理失败的图片 ===")
for i, file in enumerate(failed_files, 1):
print(f"{i}. {file}")

if __name__ == "__main__":
print("=== 图片批量处理工具 ===")
print("功能说明:")
print("1. 将大于指定分辨率的图片调整为不超过该尺寸")
print("2. 可选择是否复制未处理的照片到新文件夹")
print("3. 保持原始目录结构\n")

# 获取用户输入
input_folder = input("请输入源文件夹路径: ").strip()
output_folder = input("请输入目标文件夹路径: ").strip()
max_width, max_height = get_resolution_input("请输入目标分辨率(格式: 宽 高,例如480 640): ")
copy_choice = input("是否需要将未处理的照片一并复制到新文件夹? (y/n): ").strip().lower()

if not os.path.exists(input_folder):
print("错误: 源文件夹不存在!")
else:
try:
process_images(
input_folder=input_folder,
output_folder=output_folder,
max_width=max_width,
max_height=max_height,
copy_untouched=copy_choice == 'y'
)
except KeyboardInterrupt:
print("\n操作已取消")
except Exception as e:
print(f"发生错误: {str(e)}")
finally:
input("\n按Enter键退出...")

实现效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
D:\pic>python t1.py
=== 图片批量处理工具 ===
功能说明:
1. 将大于指定分辨率的图片调整为不超过该尺寸
2. 可选择是否复制未处理的照片到新文件夹
3. 保持原始目录结构

请输入源文件夹路径: D:\pic\1\img
请输入目标文件夹路径: D:\pic\2
请输入目标分辨率(格式: 宽 高,例如480 640): 480 640
是否需要将未处理的照片一并复制到新文件夹? (y/n): n
[处理] D:\pic\1\img\icon.jpg -> D:\pic\2\.\icon.jpg
[处理] D:\pic\1\img\微信图片_20240122114812.jpg -> D:\pic\2\.\微信图片_20240122114812.jpg
[处理] D:\pic\1\img\微信图片_20241231173335.jpg -> D:\pic\2\.\微信图片_20241231173335.jpg

=== 处理结果 ===
目标分辨率: 480×640
已处理图片数量: 3
跳过图片数量: 0
失败图片数量: 0

按Enter键退出...