38 lines
1.8 KiB
Python
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}")
|