o2o-infinith-demo/supporters/scripts/img_process.py

38 lines
1.8 KiB
Python

#!/usr/bin/env python3
"""이미지 검사·리사이즈 (collect_images.mjs 가 호출). 입력 파일을 열어 크기를 확인하고 최대 폭으로 줄여 JPEG 로 저장한다.
사용: img_process.py <in> <out.jpg> <max_width> <min_width>
출력: "ok <w> <h>" 또는 "skip <이유>". 애니메이션 GIF·너무 작은 이미지·극단적 비율은 skip."""
import sys
from PIL import Image, ImageOps
src, dst, max_w, min_w = sys.argv[1], sys.argv[2], int(sys.argv[3]), int(sys.argv[4])
try:
im = Image.open(src)
if getattr(im, "is_animated", False) and im.n_frames > 1:
print("skip animated"); sys.exit(0)
im = ImageOps.exif_transpose(im)
w, h = im.size
if w < min_w:
print(f"skip small {w}x{h}"); sys.exit(0)
ratio = w / h if h else 0
if ratio < 0.4 or ratio > 2.6:
print(f"skip ratio {w}x{h}"); sys.exit(0)
if im.mode in ("RGBA", "LA", "P"):
bg = Image.new("RGB", im.size, (255, 255, 255))
bg.paste(im.convert("RGBA"), mask=im.convert("RGBA").split()[-1])
im = bg
else:
im = im.convert("RGB")
# 글자만 있는 마케팅 블록(흰 배경 위 문구)·장식 오브젝트 제외: 흰 배경으로 평탄화한 뒤 축소본에서 거의 흰 픽셀 비율이 80% 이상이면 건너뛴다
small = im.resize((64, max(1, round(64 * h / w))))
px = list(small.getdata())
white = sum(1 for r, g, b in px if r > 235 and g > 235 and b > 235) / max(1, len(px))
if white >= 0.80:
print(f"skip textblock white={white:.2f}"); sys.exit(0)
if w > max_w:
im = im.resize((max_w, round(h * max_w / w)), Image.LANCZOS)
im.save(dst, "JPEG", quality=85, optimize=True)
print(f"ok {im.size[0]} {im.size[1]}")
except Exception as e: # noqa: BLE001
print(f"skip error {e}")