50 lines
2.1 KiB
Python
50 lines
2.1 KiB
Python
from PIL import Image
|
||
import os
|
||
from config import Config
|
||
from logger import logger
|
||
|
||
class ImageProcessor:
|
||
@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):
|
||
"""转换图片格式,可选缩放(尺寸解析在外部处理)"""
|
||
try:
|
||
with Image.open(input_path) as img:
|
||
# 转换模式(RGBA转RGB对于JPEG)
|
||
if target_format.lower() in ['jpg', 'jpeg'] and img.mode in ('RGBA', 'P'):
|
||
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
|
||
save_kwargs = {}
|
||
if target_format.lower() in ['jpg', 'jpeg', 'webp']:
|
||
save_kwargs['quality'] = quality if quality is not None else Config.DEFAULT_QUALITY
|
||
img.save(output_path, format=target_format.upper(), **save_kwargs)
|
||
logger.info(f"转换成功: {input_path} -> {output_path}")
|
||
return True
|
||
except Exception as e:
|
||
logger.error(f"转换失败 {input_path}: {e}")
|
||
return False |