4706e2669c
An Android duplicate-photo finder. Pure-Kotlin core (SHA-256 + dHash hashing, exact and perceptual union-find grouping, three sensitivity presets) with MediaStore access, a persistent SQLite hash index and a tiered ScanEngine behind a Jetpack Compose UI. No INTERNET permission, no ads, no analytics, no account. Ships versionCode 2 / versionName 1.0.1, carrying the scan-stall hardening (BoundedCall breaker) and verified against a 5,363-photo device library. 80 JVM unit tests, lint clean. Release paperwork is in docs/ (Play checklist, store listing, edge-case testing), the upload-ready Play graphics and screenshots in store-assets/, and the generators for those assets in tools/.
63 lines
2.5 KiB
Bash
Executable File
63 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Turns raw device screenshots into Play-legal store screenshots.
|
|
#
|
|
# ./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
|
|
#
|
|
# 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.
|
|
#
|
|
# 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:
|
|
#
|
|
# 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)
|
|
#
|
|
# 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.
|
|
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}"
|
|
|
|
if [ ! -d "$raw" ]; then
|
|
echo "usage: $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"
|
|
|
|
shopt -s nullglob
|
|
for f in "$raw"/*.png; 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.
|
|
keep=$(( height - status_bar - nav_bar ))
|
|
cap=$(( width * 2 ))
|
|
if [ "$keep" -gt "$cap" ]; then
|
|
keep="$cap"
|
|
fi
|
|
|
|
magick "$f" -crop "${width}x${keep}+0+${status_bar}" +repage \
|
|
-background '#FFFBFE' -alpha remove -alpha off PNG24:"$out/$name"
|
|
printf ' %s %s -> ' "$name" "$(identify -format '%wx%h' "$f")"
|
|
identify -format '%wx%h %[channels] %b\n' "$out/$name"
|
|
done
|