留存代码,以备不时之需。
主要功能:将文件夹内的图片及子文件夹内的图片进行压缩,所有大于300KB的都压缩至小于300KB。会直接覆盖。
import os,io
from PIL import Image
"""批量压缩图片大小:首先判断是否为图片,获取图片大小,判断是否大于300KB,
对于小于300KB的不做处理,对于大于300KB的,在锁定纵横比的情况下,压缩至290KB。
根据以上要求,遍历所有文件夹内的图片及嵌套文件内的图片进行处理。"""
def get_file_size(file_path):
"""获取文件大小,单位为KB"""
return os.path.getsize(file_path) / 1024
def compress_image(image_path, target_size_kb=290): #为确保图片大小压缩后小于300kb,程序指标设置为290.
"""在保持纵横比的情况下压缩图片到指定大小(KB)附近"""
original_size = get_file_size(image_path)
if original_size <= target_size_kb:
print(f"跳过 {image_path}:原始大小 {original_size:.2f} KB,小于或等于目标大小。")
return
img = Image.open(image_path)
# 获取图片原始尺寸
original_width, original_height = img.size
# 压缩比从100%开始尝试,逐步降低
quality = 95
while True:
# 保存图片到内存(不保存到磁盘),以评估压缩后的大小
img_byte_arr = io.BytesIO()
img.save(img_byte_arr, format='JPEG', quality=quality)
img_byte_arr = img_byte_arr.getvalue()
compressed_size = len(img_byte_arr) / 1024
# 如果大小接近或小于目标大小,则退出循环
if compressed_size <= target_size_kb:
break
# 否则,降低质量并继续尝试
quality -= 5
if quality < 10:
print(f"警告:无法将 {image_path} 压缩到 {target_size_kb} KB 以下,使用最低质量。")
break
# 如果需要,将压缩后的图片写回文件(这里演示不实际写入)
img.save(image_path, format='JPEG', quality=quality)
print(f"压缩 {image_path}:原始大小 {original_size:.2f} KB,压缩后大小 {compressed_size:.2f} KB。")
def traverse_and_compress(root_dir):
"""遍历指定目录及其子目录,并压缩大于300KB的图片"""
for root, dirs, files in os.walk(root_dir):
for file in files:
if file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
file_path = os.path.join(root, file)
compress_image(file_path)
# 设置要遍历的根目录
root_directory = r"C:\Users\Administrator\Desktop\****" # 替换为需要处理的图片所在文件夹路径
traverse_and_compress(root_directory)