Files
mailc/image_processor.py
T

75 lines
2.7 KiB
Python
Raw Normal View History

2026-04-18 23:04:03 +08:00
from PIL import Image
import os
from config import Config
from logger import logger
class ImageProcessor:
2026-04-18 23:58:27 +08:00
# 格式映射:将常见的小写格式名转换为 Pillow 可识别的格式名
FORMAT_MAP = {
'jpg': 'JPEG',
'jpeg': 'JPEG',
'png': 'PNG',
'webp': 'WEBP',
'gif': 'GIF',
'bmp': 'BMP',
'tiff': 'TIFF',
}
2026-04-18 23:04:03 +08:00
@staticmethod
def resize_by_ratio(img, ratio_width, ratio_height):
"""等比例缩放至目标比例(最长边适配)"""
w, h = img.size
target_ratio = ratio_width / ratio_height
current_ratio = w / h
if current_ratio > target_ratio:
new_w = int(h * target_ratio)
new_h = h
else:
new_w = w
new_h = int(w / target_ratio)
return img.resize((new_w, new_h), Image.Resampling.LANCZOS)
@staticmethod
def resize_by_pixel(img, target_width, target_height):
"""等比例缩放至不超过目标像素(保持比例,以较长边为准)"""
w, h = img.size
ratio_w = target_width / w
ratio_h = target_height / h
ratio = min(ratio_w, ratio_h)
new_w = int(w * ratio)
new_h = int(h * ratio)
return img.resize((new_w, new_h), Image.Resampling.LANCZOS)
@staticmethod
def convert_image(input_path, output_path, target_format, quality=None):
2026-04-18 23:58:27 +08:00
"""
转换图片格式
target_format: 小写字符串,如 'jpg', 'png', 'webp'
"""
2026-04-18 23:04:03 +08:00
try:
with Image.open(input_path) as img:
2026-04-18 23:58:27 +08:00
# 获取 Pillow 标准格式名
pillow_format = ImageProcessor.FORMAT_MAP.get(target_format.lower())
if pillow_format is None:
logger.error(f"不支持的输出格式: {target_format}")
return False
# 对于 JPEG 格式,需要处理透明通道
if pillow_format == 'JPEG' and img.mode in ('RGBA', 'P'):
2026-04-18 23:04:03 +08:00
rgb_img = Image.new('RGB', img.size, (255, 255, 255))
rgb_img.paste(img, mask=img.split()[-1] if img.mode == 'RGBA' else None)
img = rgb_img
2026-04-18 23:58:27 +08:00
2026-04-18 23:04:03 +08:00
save_kwargs = {}
2026-04-18 23:58:27 +08:00
if pillow_format in ('JPEG', 'WEBP'):
2026-04-18 23:04:03 +08:00
save_kwargs['quality'] = quality if quality is not None else Config.DEFAULT_QUALITY
2026-04-18 23:58:27 +08:00
elif pillow_format == 'PNG':
save_kwargs['compress_level'] = 6
img.save(output_path, format=pillow_format, **save_kwargs)
2026-04-18 23:04:03 +08:00
logger.info(f"转换成功: {input_path} -> {output_path}")
return True
except Exception as e:
logger.error(f"转换失败 {input_path}: {e}")
2026-04-18 23:58:27 +08:00
return False