3bc1263294
build / build (push) Successful in 4m8s
android/ links engine/src/ and interpreter/src/ via JNI/CMake (real astronomy.c, not the watch's size-constrained substitute), rendering through Jetpack Compose with a burger-menu config page mirroring WatchConfig and a WorkManager-driven daily notification. Independent of the watch app - neither requires the other. build-image now bundles the Android SDK/NDK alongside the Pebble SDK (VERSION bumped to 2), and .gitea/workflows/build.yml/Makefile/ run-image.sh build and publish the APK the same way as the CLI tarball and .pbw.
83 lines
3.3 KiB
Python
83 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Downsizes ../../res/img/*.jpeg into app/src/main/res/drawable-nodpi/*.webp
|
|
for the Android app.
|
|
|
|
Structurally a sibling of ../../watch/scripts/gen_card_images.py (same
|
|
CARDS slug/filename table - matching engine/src/tarot_data.c's own
|
|
k_card_slug, so app/src/main/res/drawable-nodpi/<slug>.webp resolves via
|
|
plain resource-name lookup, see app/src/main/java/.../ui/CardArt.kt -
|
|
and the same per-file mtime skip-if-up-to-date logic), but sized and
|
|
encoded for a phone screen instead of Pebble's hardware-forced 72px PNG:
|
|
400px wide, lossy WebP (quality 85) - these are painted illustrations,
|
|
not line art, so WebP meaningfully beats PNG here, and 21MB of source
|
|
JPEGs would otherwise bloat the APK.
|
|
|
|
Generated output, not committed (see the repo's root .gitignore's
|
|
/android/app/src/main/res/drawable-nodpi entry) - regenerate by running
|
|
this script directly or via Gradle's generateCardArt task (wired into
|
|
app's preBuild, see ../app/build.gradle.kts). Requires Pillow (`pip
|
|
install Pillow`), already part of build-image's toolchain.
|
|
"""
|
|
import os
|
|
import sys
|
|
|
|
from PIL import Image
|
|
|
|
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
SRC_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, "..", "..", "res", "img"))
|
|
OUT_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, "..", "app", "src", "main", "res", "drawable-nodpi"))
|
|
|
|
CARD_WIDTH = 400
|
|
WEBP_QUALITY = 85
|
|
|
|
# (source file in res/img/, slug matching engine/src/tarot_data.c's
|
|
# k_card_slug table) - in TarotCard enum order (CARD_FOOL = 0 ... CARD_WORLD).
|
|
CARDS = [
|
|
("RWS_Tarot_00_Fool.jpeg", "fool"),
|
|
("RWS_Tarot_01_Magician.jpeg", "magician"),
|
|
("RWS_Tarot_02_High_Priestess.jpeg", "high_priestess"),
|
|
("RWS_Tarot_03_Empress.jpeg", "empress"),
|
|
("RWS_Tarot_04_Emperor.jpeg", "emperor"),
|
|
("RWS_Tarot_05_Hierophant.jpeg", "hierophant"),
|
|
("RWS_Tarot_06_Lovers.jpeg", "lovers"),
|
|
("RWS_Tarot_07_Chariot.jpeg", "chariot"),
|
|
("RWS_Tarot_08_Strength.jpeg", "strength"),
|
|
("RWS_Tarot_09_Hermit.jpeg", "hermit"),
|
|
("RWS_Tarot_10_Wheel_of_Fortune.jpeg", "wheel_of_fortune"),
|
|
("RWS_Tarot_11_Justice.jpeg", "justice"),
|
|
("RWS_Tarot_12_Hanged_Man.jpeg", "hanged_man"),
|
|
("RWS_Tarot_13_Death.jpeg", "death"),
|
|
("RWS_Tarot_14_Temperance.jpeg", "temperance"),
|
|
("RWS_Tarot_15_Devil.jpeg", "devil"),
|
|
("RWS_Tarot_16_Tower.jpeg", "tower"),
|
|
("RWS_Tarot_17_Star.jpeg", "star"),
|
|
("RWS_Tarot_18_Moon.jpeg", "moon"),
|
|
("RWS_Tarot_19_Sun.jpeg", "sun"),
|
|
("RWS_Tarot_20_Judgement.jpeg", "judgement"),
|
|
("RWS_Tarot_21_World.jpeg", "world"),
|
|
]
|
|
|
|
|
|
def main():
|
|
os.makedirs(OUT_DIR, exist_ok=True)
|
|
written = 0
|
|
for src_name, slug in CARDS:
|
|
src_path = os.path.join(SRC_DIR, src_name)
|
|
out_path = os.path.join(OUT_DIR, f"{slug}.webp")
|
|
|
|
if os.path.exists(out_path) and os.path.getmtime(out_path) >= os.path.getmtime(src_path):
|
|
continue
|
|
|
|
with Image.open(src_path) as img:
|
|
ratio = CARD_WIDTH / img.width
|
|
height = round(img.height * ratio)
|
|
resized = img.convert("RGB").resize((CARD_WIDTH, height), Image.LANCZOS)
|
|
resized.save(out_path, "WEBP", quality=WEBP_QUALITY)
|
|
written += 1
|
|
|
|
print(f"wrote {written}/{len(CARDS)} card images to {OUT_DIR}", file=sys.stderr)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|