- Caption-localized the 5 iPhone 6.7" + 5 iPad 12.9" screenshots into the 5 non-English locales, reusing the en-US framed captures (in-frame UI stays EN). Tooling in fastlane/screenshot_localize/ (Pillow: repaints the pastel caption band, re-renders headline/subtitle in SF Pro; auto-fits + wraps per language). - Rewrote release_notes 1.2.0 in all 6 languages: since 1.1.5 never shipped publicly (last public = 1.1.4), the notes consolidate 1.1.5 + 1.2.0 features. - Fastfile: new `publish` lane — uploads metadata + screenshots for an existing TestFlight build (skip_binary_upload, no submit) so offer codes can be set up before submission. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BkanrydYtrme8wipTzWssG
3.1 KiB
Task: generate localized App Store screenshots for MealMood
Write generate.py (run with uv run --with Pillow python3 generate.py from the
fastlane/screenshots/_localize/ directory) that produces localized marketing
screenshots by re-rendering ONLY the top caption text of each base image.
Base images (source of truth — do NOT alter the phone/app area)
fastlane/screenshots/en-US/ contains 5 screenshots × 2 devices:
- iPhone 6.7":
{i}_APP_IPHONE_67_{i}.png(1320 × 2868) - iPad 12.9":
{i}_APP_IPAD_PRO_3GEN_129_{i}.png(2048 × 2732) for i in 0..4.
Each image = flat pastel background at top holding a headline (bold, black, centered, 1–3 lines) + a subtitle (regular, black, centered, ~2 lines), with a device frame containing an app screenshot BELOW the text.
What to do, per language × per base image
Languages (output folders, siblings of en-US/): es-ES de-DE fr-FR it pt-BR.
Also re-render en-US in place is NOT needed — leave en-US untouched.
Text comes from translations.json (index 0..4 matches file index i).
For each base image:
- Read background color = pixel at (10,10).
- Detect
phone_top= first row y in [0.10h, 0.6h] that contains a horizontal contiguous run of near-black pixels (r,g,b all < 70) wider than 0.35·w. This is the top of the device — the caption band is[0, phone_top). - Repaint the whole band
[0, phone_top)with the background color (this erases the English caption). - Draw the localized headline + subtitle, black, centered horizontally,
the text block vertically centered within
[0, phone_top)with a slight upward bias (leave ~12% of phone_top as bottom gap before the phone). - Save to
../<lang>/<same_filename>.
Typography (match the original as closely as possible)
- Font: SF Pro via
/System/Library/Fonts/SFNS.ttf(variable font — usefont.set_variation_by_name). Headline = Bold, subtitle = Regular. If a weight name isn't found, print the available names once and pick the closest (Bold/Semibold for headline, Regular for sub). - iPhone: headline ~72px, subtitle ~50px as a STARTING point. iPad: headline ~96px, subtitle ~66px starting point.
- Auto-fit: if the headline at the start size would exceed 88% of image width on its longest line, reduce the headline font size until it fits (min 44px iPhone / 60px iPad). Wrap headline to at most 3 lines, subtitle to at most 3 lines, breaking on spaces. Some localized headlines are long (e.g. the it/fr "…in famiglia è facile") — wrapping + shrinking must keep them inside the band and never overlap the phone.
- Line spacing ~1.12×. Gap between headline block and subtitle ~0.5× subtitle font size. Colour pure black (0,0,0). Antialiased.
Output & self-check
- Every output PNG must keep the EXACT same dimensions as its base.
- After generating, print a table: lang, index, device, headline font px used, #headline lines, #subtitle lines, and whether text bottom < phone_top (must be true for all — flag any that fail).
- Do not touch any file outside the five language folders.
Total output = 5 langs × 5 indices × 2 devices = 60 images.