trace/services/notify-gateway/notifiers/image_utils.py
Lee 19afaffbb7
All checks were successful
Java Maven 3.9.9 & JDK 26 CI/CD Pipeline / build-and-deploy (push) Successful in 3m22s
feat: add shared notification gateway
2026-09-07 17:50:25 +08:00

53 lines
1.8 KiB
Python

import io
from pathlib import Path
from PIL import Image, ImageOps
from .base import ImageAttachment
INLINE_IMAGE_MAX_BYTES = 2_000_000
PREVIEW_TARGET_BYTES = 1_900_000
WECOM_FILE_MAX_BYTES = 20_000_000
TELEGRAM_PHOTO_MAX_BYTES = 10_000_000
TELEGRAM_FILE_MAX_BYTES = 50_000_000
def compressed_preview(image: ImageAttachment) -> ImageAttachment:
if len(image.data) <= INLINE_IMAGE_MAX_BYTES:
return image
with Image.open(io.BytesIO(image.data)) as source:
source.load()
working = ImageOps.exif_transpose(source)
if working.mode in {"RGBA", "LA"}:
background = Image.new("RGB", working.size, "white")
alpha = working.getchannel("A")
background.paste(working.convert("RGB"), mask=alpha)
working = background
elif working.mode != "RGB":
working = working.convert("RGB")
current = working
while True:
for quality in (90, 82, 74, 66, 58, 50, 42, 34):
output = io.BytesIO()
current.save(
output,
format="JPEG",
quality=quality,
optimize=True,
progressive=True,
)
data = output.getvalue()
if len(data) <= PREVIEW_TARGET_BYTES:
name = f"{Path(image.filename).stem}-preview.jpg"
return ImageAttachment(name, "image/jpeg", data)
width, height = current.size
if min(width, height) <= 128:
raise RuntimeError("image cannot be compressed below preview limit")
current = current.resize(
(max(1, int(width * 0.8)), max(1, int(height * 0.8))),
Image.Resampling.LANCZOS,
)