Initial commit: Foto Dup Finder 1.0.1
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/.
This commit is contained in:
Executable
+62
@@ -0,0 +1,62 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user