Files
juzi/tools/prepare_h5_assets.py
T

44 lines
2.2 KiB
Python

#!/usr/bin/env python3
"""Derive H5 crops from exported PSD assets; never crop the original exports."""
from pathlib import Path
from PIL import Image
import json
import cv2
import numpy as np
root = Path(__file__).resolve().parents[1] / 'h5/assets/img/ui-20261009'
for name in ['bg-splash', 'bg-login', 'bg-profile', 'bg-history', 'bg-report']:
source = Image.open(root / (name + '.jpg'))
# Native status/navigation area belongs to the host, not the H5 document.
top = 253 if name == 'bg-report' else 248
source.crop((0, top, source.width, source.height)).save(root / (name + '-h5.jpg'), quality=92, optimize=True)
# Mobile delivery variant; preserve the full-resolution PSD exports/JPEGs.
Image.open(root / (name + '-h5.jpg')).save(root / (name + '-h5.webp'), quality=85, method=6)
geometry = []
for direction in ['front', 'left', 'right']:
alpha = np.array(Image.open(root / ('camera-mask-' + direction + '.png')).getchannel('A'))
contours, _ = cv2.findContours((alpha < 100).astype('uint8'), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contour = max((c for c in contours if 500 < cv2.boundingRect(c)[1] < 1600), key=cv2.contourArea)
points = cv2.approxPolyDP(contour, 1.4, True).reshape(-1, 2)
outline = 'M' + 'L'.join(f'{x/2.88:.2f},{y/2.88:.2f}' for x, y in points) + 'Z'
guide_alpha = np.array(Image.open(root / ('camera-guide-' + direction + '.png')).getchannel('A'))
count, labels, stats, _ = cv2.connectedComponentsWithStats((guide_alpha > 100).astype('uint8'))
guides = []
for i in range(1, count):
x, y, w, h, area = stats[i]
if area < 50:
continue
points = []
if w > h:
for col in range(x, x+w, 3):
rows = np.where(labels[:, col] == i)[0]
if len(rows): points.append((col, rows.mean()))
else:
for row in range(y, y+h, 3):
cols = np.where(labels[row, :] == i)[0]
if len(cols): points.append((cols.mean(), row))
guides.append('M' + 'L'.join(f'{px/2.88:.2f},{py/2.88:.2f}' for px, py in points))
geometry.append({'outline': outline, 'guides': guides})
(root.parents[2] / 'js/camera-geometry.js').write_text('window.CameraGeometry = ' + json.dumps(geometry) + ';\n')