# -*- coding: utf-8 -*- """ 图片预检 - 下载后检查尺寸/格式/是否损坏,不合格直接拒单 """ import os import logging from typing import Tuple logger = logging.getLogger(__name__) # 可配置 MIN_WIDTH = int(os.getenv("IMAGE_PRECHECK_MIN_WIDTH", "50")) MIN_HEIGHT = int(os.getenv("IMAGE_PRECHECK_MIN_HEIGHT", "50")) MAX_WIDTH = int(os.getenv("IMAGE_PRECHECK_MAX_WIDTH", "8000")) MAX_HEIGHT = int(os.getenv("IMAGE_PRECHECK_MAX_HEIGHT", "8000")) MIN_SIZE = int(os.getenv("IMAGE_PRECHECK_MIN_BYTES", "100")) # 至少 100 字节 MAX_SIZE = int(os.getenv("IMAGE_PRECHECK_MAX_BYTES", "0")) # 0=不限制 SUPPORTED_FORMATS = (".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp") def precheck(local_path: str) -> Tuple[bool, str]: """ 预检图片文件。 Returns: (ok, message) - ok=False 时 message 为拒单原因 """ if not os.path.exists(local_path): return False, "图片文件不存在" size = os.path.getsize(local_path) if size < MIN_SIZE: return False, f"图片太小({size} 字节),可能损坏或格式异常" if MAX_SIZE > 0 and size > MAX_SIZE: return False, f"图片过大({size/1024/1024:.1f}MB),超过 {MAX_SIZE/1024/1024:.0f}MB 限制" try: from PIL import Image with Image.open(local_path) as img: w, h = img.size if w < MIN_WIDTH or h < MIN_HEIGHT: return False, f"图片尺寸过小({w}x{h}),最小 {MIN_WIDTH}x{MIN_HEIGHT}" if w > MAX_WIDTH or h > MAX_HEIGHT: return False, f"图片尺寸过大({w}x{h}),最大 {MAX_WIDTH}x{MAX_HEIGHT}" img.verify() except Exception as e: return False, f"图片无法读取或已损坏:{str(e)[:50]}" return True, ""