40 lines
1.5 KiB
Python
40 lines
1.5 KiB
Python
"""上传图片的尺寸闸。
|
||
|
||
火山素材审核要求图片宽高在 300–6000 px 之间,小图会被
|
||
[InvalidParameter.WidthTooSmall] 拒掉。这个限制以前只在自由创作的素材上传口做,
|
||
商品图 / 项目上传等入口没有 —— 小图能一路存进商品库,直到生成视频送审那一刻才炸,
|
||
而且报错发生在离上传很远的地方,用户根本对不上号。统一在入库前挡住。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from io import BytesIO
|
||
|
||
MIN_EDGE = 300
|
||
MAX_EDGE = 6000
|
||
|
||
|
||
class ImageTooSmallError(ValueError):
|
||
"""尺寸不合格。文案直接面向用户。"""
|
||
|
||
|
||
def probe_image_size(raw: bytes) -> tuple[int, int]:
|
||
"""读图片宽高。读不出来抛 ImageTooSmallError(当成坏文件)。"""
|
||
from PIL import Image
|
||
|
||
try:
|
||
with Image.open(BytesIO(raw)) as im:
|
||
return int(im.width), int(im.height)
|
||
except Exception as exc: # noqa: BLE001
|
||
raise ImageTooSmallError("图片解析失败,请更换文件") from exc
|
||
|
||
|
||
def ensure_reviewable_image(raw: bytes, *, label: str = "图片") -> tuple[int, int]:
|
||
"""校验上传图片的宽高,返回 (width, height)。不合格抛 ImageTooSmallError。"""
|
||
width, height = probe_image_size(raw)
|
||
if not (MIN_EDGE <= width <= MAX_EDGE and MIN_EDGE <= height <= MAX_EDGE):
|
||
raise ImageTooSmallError(
|
||
f"{label}尺寸需在 {MIN_EDGE}–{MAX_EDGE} 像素之间(当前 {width}×{height}),"
|
||
"过小的图无法通过素材审核,请换一张更大的图"
|
||
)
|
||
return width, height
|