first commit
This commit is contained in:
52
controllers/compress_image.py
Normal file
52
controllers/compress_image.py
Normal file
@@ -0,0 +1,52 @@
|
||||
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 ''
|
||||
Reference in New Issue
Block a user