53 lines
1.7 KiB
Python
53 lines
1.7 KiB
Python
import os
|
||
from PIL import Image
|
||
from models.logger import setup_logger
|
||
|
||
logger = setup_logger()
|
||
|
||
def compress_image(input_path, output_folder: str = 'compressed_images', target_kb=200, quality_step=5) -> str:
|
||
"""
|
||
将图片压缩到指定大小(以KB为单位)
|
||
|
||
Args:
|
||
input_path: 输入图片路径
|
||
output_folder: 输出文件夹
|
||
target_kb: 目标文件大小(默认200KB)
|
||
quality_step: 每次迭代中质量减少的步长(默认5)
|
||
|
||
Returns:
|
||
压缩后的图片路径
|
||
"""
|
||
# 确保输出文件夹存在
|
||
os.makedirs(output_folder, exist_ok=True)
|
||
|
||
# 获取文件基本信息
|
||
file_size_kb = os.path.getsize(input_path) / 1024
|
||
base_name = os.path.basename(input_path)
|
||
output_path = os.path.join(output_folder, base_name.rsplit('.', 1)[0] + '.jpg') # 默认转为jpg
|
||
|
||
if file_size_kb <= target_kb:
|
||
# 如果文件小于等于目标大小,直接复制
|
||
img = Image.open(input_path)
|
||
if img.mode in ("RGBA", "P"):
|
||
img = img.convert("RGB")
|
||
img.save(output_path, "JPEG", optimize=True, quality=95)
|
||
return str(output_path)
|
||
|
||
# 初始质量设置
|
||
quality = 85
|
||
|
||
while quality > 10: # 设置最低质量限制避免过低质量的图片
|
||
with Image.open(input_path) as img:
|
||
if img.mode in ("RGBA", "P"):
|
||
img = img.convert("RGB")
|
||
img.save(output_path, "JPEG", optimize=True, quality=quality)
|
||
|
||
# 检查文件大小
|
||
if os.path.getsize(output_path) / 1024 < target_kb:
|
||
return str(output_path)
|
||
|
||
quality -= quality_step # 减少质量设置
|
||
|
||
logger.error(f"图片 {input_path} 压缩失败!")
|
||
return ''
|