feat: make the store-screenshot normaliser form-factor aware
Play gives phones and each tablet size a screenshot slot of their own (Phone, 7-inch tablet, 10-inch tablet) and asks for at least four screenshots per large-screen form factor, so the normaliser takes FORM_FACTOR=phone|tablet-7in|tablet-10in and keeps one raw and one output directory per factor: store-assets/raw-screenshots/<form-factor>/ adb captures (git-ignored) store-assets/screenshots/<form-factor>/ what gets uploaded The tablet form factors crop 0 px of system chrome on purpose, and that is checked rather than guessed: every tablet profile in the SDK's own device definitions is already inside Play's 2:1 cap (7in WSVGA 1024x600, 10.1in WXGA 1280x800, Nexus 7 2013 1200x1920, and Nexus 10 / Medium Tablet / Pixel Tablet at 2560x1600), so the 93/130 px phone crop exists only because a 1080x2400 phone frame is 2.22:1. Cropping a tablet is therefore cosmetic, and is now opt-in through STATUS_BAR_PX / NAV_BAR_PX. The 2:1 clamp still runs for every form factor, and each file is now checked against Play's limits as it is written (shorter side >= 320 px, longer side <= 3840 px) - the phone captures only ever got that check by hand. A missing input directory or an unknown form factor now fails with an actionable message instead of a bash error. The four existing phone captures move to raw-screenshots/phone/ and normalise to the same 1080x2160 RGB files as before, byte for byte. The 7-inch and 10-inch captures were taken with this script on AOSP AVDs; how, and the numbers they show, are recorded in docs/STORE_LISTING.md. tools/make-store-assets.sh now prints the two tablet invocations as well, so the obvious next step after generating the icon and feature graphic is not the phone-only one.
This commit is contained in:
@@ -1,54 +1,94 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Turns raw device screenshots into Play-legal store screenshots.
|
||||
# Turns raw device screenshots into Play-legal store screenshots, one directory per form
|
||||
# factor, because Play gives phones and each tablet size their own slot.
|
||||
#
|
||||
# ./tools/make-store-screenshots.sh [raw-dir] [output-dir]
|
||||
#
|
||||
# Both paths default to inside the repo, never to $HOME:
|
||||
# raw store-assets/raw-screenshots/ git-ignored staging for the `adb` captures
|
||||
# output store-assets/screenshots/ the cropped files that get uploaded to Play
|
||||
# FORM_FACTOR selects the Play Console slot the captures belong to
|
||||
# (Main store listing > Graphics > Phone / 7-inch tablet / 10-inch tablet):
|
||||
#
|
||||
# Why this exists: Play rejects a screenshot whose longer side is more than twice its
|
||||
# shorter side ("your screenshot's maximum dimension can't be more than twice its minimum
|
||||
# dimension"). A 1080 x 2400 phone capture is 2.22:1, so it has to become 1080 x 2160.
|
||||
# FORM_FACTOR=phone (default) store-assets/raw-screenshots/phone/ -> store-assets/screenshots/phone/
|
||||
# FORM_FACTOR=tablet-7in store-assets/raw-screenshots/tablet-7in/ -> store-assets/screenshots/tablet-7in/
|
||||
# FORM_FACTOR=tablet-10in store-assets/raw-screenshots/tablet-10in/ -> store-assets/screenshots/tablet-10in/
|
||||
#
|
||||
# The crop removes system chrome only — the status bar at the top, the navigation bar at the
|
||||
# bottom — never app content. Both heights were measured on the test device:
|
||||
# Both paths are inside the repo, never in $HOME. Pass raw-dir / output-dir positionally to
|
||||
# override them (that is what the tests and one-off captures use).
|
||||
#
|
||||
# STATUS_BAR_PX ITYPE_STATUS_BAR frame height 93 px (1080 x 2400 @ 440 dpi)
|
||||
# NAV_BAR_PX ITYPE_NAVIGATION_BAR bottom inset 130 px (same device)
|
||||
# Why this exists: Play rejects a screenshot whose longer side is more than twice its shorter
|
||||
# side ("The maximum dimension of your screenshot can't be more than twice as long as the
|
||||
# minimum dimension"), and requires 24-bit PNG or JPEG without alpha, a shorter side of at
|
||||
# least 320 px and a longer side of at most 3840 px.
|
||||
#
|
||||
# Phone A 1080 x 2400 capture is 2.22:1 and has to lose system chrome to reach the 2:1
|
||||
# cap. Both bar heights were measured on the test device:
|
||||
#
|
||||
# STATUS_BAR_PX ITYPE_STATUS_BAR frame height 93 px (1080 x 2400 @ 440 dpi)
|
||||
# NAV_BAR_PX ITYPE_NAVIGATION_BAR bottom inset 130 px (same device)
|
||||
#
|
||||
# Tablet No tablet screen Android ships is anywhere near 2:1 — the 7" WSVGA profile is
|
||||
# 1024 x 600 (1.71:1) and the 10-inch profiles (10.1" WXGA, Nexus 10, Medium
|
||||
# Tablet, Pixel Tablet) are 1280 x 800 or 2560 x 1600 (1.60:1) — so a tablet frame
|
||||
# is already legal and crops 0 px by default. Cropping chrome there is cosmetic
|
||||
# only, so it is opt-in: measure on your device and pass the insets.
|
||||
#
|
||||
# Measure either device with (the bar heights are device- and OEM-specific, and MIUI is not
|
||||
# AOSP: the AOSP defaults would have been 24 dp and 48 dp):
|
||||
#
|
||||
# adb shell dumpsys window displays | grep -oE 'ITYPE_STATUS_BAR frame=\[[^]]*\]\[[^]]*\]'
|
||||
# adb shell dumpsys window displays | grep -oE 'control type=ITYPE_NAVIGATION_BAR.*mInsetsHint=\{[^}]*\}'
|
||||
#
|
||||
# Output is 24-bit PNG without alpha, which is what Play asks for. Captures are not shot by
|
||||
# this script — take them yourself (the shot list is in docs/STORE_LISTING.md) and drop them
|
||||
# into store-assets/raw-screenshots/, or pass the directory as the first argument.
|
||||
# The crop removes system chrome only, never app content. Output is 24-bit PNG without alpha,
|
||||
# which is what Play asks for. Captures are not shot by this script — take them yourself (the
|
||||
# shot list is in docs/STORE_LISTING.md) and drop them into the raw directory, or pass that
|
||||
# directory as the first argument.
|
||||
set -euo pipefail
|
||||
|
||||
here="$(cd "$(dirname "$0")" && pwd)"
|
||||
repo="$(dirname "$here")"
|
||||
raw="${1:-$repo/store-assets/raw-screenshots}"
|
||||
out="${2:-$repo/store-assets/screenshots}"
|
||||
status_bar="${STATUS_BAR_PX:-93}"
|
||||
nav_bar="${NAV_BAR_PX:-130}"
|
||||
|
||||
form_factor="${FORM_FACTOR:-phone}"
|
||||
case "$form_factor" in
|
||||
phone) default_status_bar=93; default_nav_bar=130 ;;
|
||||
tablet-7in) default_status_bar=0; default_nav_bar=0 ;;
|
||||
tablet-10in) default_status_bar=0; default_nav_bar=0 ;;
|
||||
*)
|
||||
echo "usage: FORM_FACTOR=<phone|tablet-7in|tablet-10in> $0 [raw-dir] [output-dir]" >&2
|
||||
echo "error: unknown FORM_FACTOR '$form_factor'" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
raw="${1:-$repo/store-assets/raw-screenshots/$form_factor}"
|
||||
out="${2:-$repo/store-assets/screenshots/$form_factor}"
|
||||
status_bar="${STATUS_BAR_PX:-$default_status_bar}"
|
||||
nav_bar="${NAV_BAR_PX:-$default_nav_bar}"
|
||||
|
||||
if [ ! -d "$raw" ]; then
|
||||
echo "usage: $0 [raw-screenshot-dir] [output-dir]" >&2
|
||||
echo "usage: FORM_FACTOR=<phone|tablet-7in|tablet-10in> $0 [raw-screenshot-dir] [output-dir]" >&2
|
||||
echo "error: no such directory: $raw" >&2
|
||||
echo " capture first, e.g. adb exec-out screencap -p > $raw/01-empty.png" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
mkdir -p "$out"
|
||||
echo "$form_factor: $raw -> $out (crop ${status_bar} px status bar + ${nav_bar} px navigation bar, clamp to 2:1)"
|
||||
|
||||
shopt -s nullglob
|
||||
for f in "$raw"/*.png; do
|
||||
shots=("$raw"/*.png)
|
||||
if [ ${#shots[@]} -eq 0 ]; then
|
||||
echo "error: no .png captures in $raw" >&2
|
||||
echo " capture first, e.g. adb exec-out screencap -p > $raw/01-empty.png" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
for f in "${shots[@]}"; do
|
||||
name="$(basename "$f")"
|
||||
width="$(identify -format '%w' "$f")"
|
||||
height="$(identify -format '%h' "$f")"
|
||||
|
||||
# Drop the two system bars, then clamp to a 2:1 portrait frame.
|
||||
# Drop the two system bars (0 px for tablets, where the frame is already legal), then
|
||||
# clamp to a 2:1 portrait frame.
|
||||
keep=$(( height - status_bar - nav_bar ))
|
||||
cap=$(( width * 2 ))
|
||||
if [ "$keep" -gt "$cap" ]; then
|
||||
@@ -57,6 +97,24 @@ for f in "$raw"/*.png; do
|
||||
|
||||
magick "$f" -crop "${width}x${keep}+0+${status_bar}" +repage \
|
||||
-background '#FFFBFE' -alpha remove -alpha off PNG24:"$out/$name"
|
||||
|
||||
# Play's limits, checked on the file that actually gets uploaded rather than on the maths.
|
||||
out_width="$(identify -format '%w' "$out/$name")"
|
||||
out_height="$(identify -format '%h' "$out/$name")"
|
||||
if [ "$out_width" -lt "$out_height" ]; then
|
||||
short="$out_width"; long="$out_height"
|
||||
else
|
||||
short="$out_height"; long="$out_width"
|
||||
fi
|
||||
warn=''
|
||||
if [ "$short" -lt 320 ]; then
|
||||
warn="$warn ⚠️ shorter side under Play's 320 px minimum"
|
||||
fi
|
||||
if [ "$long" -gt 3840 ]; then
|
||||
warn="$warn ⚠️ longer side over Play's 3840 px maximum"
|
||||
fi
|
||||
|
||||
printf ' %s %s -> ' "$name" "$(identify -format '%wx%h' "$f")"
|
||||
identify -format '%wx%h %[channels] %b\n' "$out/$name"
|
||||
identify -format '%wx%h %[channels] %b' "$out/$name"
|
||||
printf '%s\n' "$warn"
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user