本代理示例可以实现:
批量压缩指定目录下的图片且支持png压缩;
压缩时支持对原图片备份;
可以指定最大图片大小;
对上述参数,可在代码中直接修改;
如果你没有PIL库,可使用pip install pillow安装
import os,io
from PIL import Image
import shutil
"""批量压缩图片大小:首先判断是否为图片,获取图片大小,判断是否大于300KB,
对于小于300KB的不做处理,对于大于300KB的,在锁定纵横比的情况下,压缩至290KB。
根据以上要求,遍历所有文件夹内的图片及嵌套文件内的图片进行处理。"""
def get_file_size(file_path):
"""获取文件大小,单位为KB"""
return os.path.getsize(file_path) / 1024
def compress_image(image_path, filetype, target_size_kb=290): #为确保图片大小压缩后小于300kb,程序指标设置为290.
"""在保持纵横比的情况下压缩图片到指定大小(KB)附近"""
print(filetype)
original_size = get_file_size(image_path)
if original_size <= target_size_kb:
print(f"跳过 {image_path}:原始大小 {original_size:.2f} KB,小于或等于目标大小。")
return
else:
if os.path.exists(image_path + "bak") == False:
shutil.copy(image_path, image_path + "bak")
if filetype == "png":
original_image = Image.open(image_path)
width, height = original_image.size
print(f"The original image size is {width} wide x {height} high")
while True:
width = int(float(width) * 0.99)
height = int(float(height) * 0.99)
resized_image = original_image.resize((width, height))
resized_image.save(image_path)
if width < 10 or height < 10:
print(f"警告:无法将 {image_path} 压缩到 {target_size_kb} KB 以下,使用最低质量。")
break
img = Image.open(image_path)
img_byte_arr = io.BytesIO()
img.save(img_byte_arr, format=filetype)
img_byte_arr = img_byte_arr.getvalue()
compressed_size = len(img_byte_arr) / 1024
# 如果大小接近或小于目标大小,则退出循环
if compressed_size <= target_size_kb:
print(f"压缩完成")
break
else:
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:
print(f"压缩完成")
break
# 否则,降低质量并继续尝试
quality -= 5
print(compressed_size)
print(quality)
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')):
# if file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
file_path = os.path.join(root, file)
filetype = file.split(".")[-1]
compress_image(file_path, filetype)
# 设置要遍历的根目录
root_directory = r"D:\cache\download\files_R4nxK.tar\files_R4nxK\files\upload" # 替换为需要处理的图片所在文件夹路径
traverse_and_compress(root_directory)