Add Google Play Store assets

This commit is contained in:
livio committed 2026-09-29 12:05:01 +02:00
1 parent a7c8127091
commit ad64d6def0
7 files changed
+203

No files matched your search

+30
View File
@@ -0,0 +1,30 @@
# Google Play Store assets
## Ready to upload
- `play-store-icon-512.png`: app icon, 512 x 512 px, PNG.
- `feature-graphic-1024x500.png`: feature graphic, 1024 x 500 px, PNG.
- `phone-01-map-1920x1080.png`: real app map view, landscape 16:9.
- `phone-02-data-drawings-1920x1080.png`: real data and drawing tools, landscape 16:9.
- `phone-03-projects-1920x1080.png`: real project archive, landscape 16:9.
The screenshots were captured from the Windows build, whose map and responsive panels match the Android app. The Windows title bar has been removed and the real app view is presented inside a 16:9 Store graphic.
## Optional Android replacements
For a later production listing, the Windows captures can be replaced with Android phone captures:
1. `phone-01-map.png`: main map with cadastral layer and one selected parcel.
2. `phone-02-project-tools.png`: project or data-and-drawings panel with useful content visible.
3. `phone-03-gps.png`: map with GPS position or a short track, without showing a private address.
4. `phone-04-export.png`: import/export tools or project archive.
Use portrait orientation and keep every image between 320 px and 3840 px per side. Do not include personal coordinates, credentials, license codes, notifications, or system dialogs.
## Store text
Short description:
`Mappe catastali, GPS, misure, progetti GIS, importazione e backup WebDAV.`
The complete Italian description is recorded in `PLAY_STORE_PRO_CHECKLIST.md` and can be pasted into Play Console.
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

+173
View File
@@ -0,0 +1,173 @@
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
ROOT = Path(__file__).resolve().parents[1]
OUTPUT = ROOT / "store-assets"
GREEN = "#075E54"
GREEN_LIGHT = "#83B6A5"
ORANGE = "#F97316"
INK = "#18342F"
PAPER = "#F7FAF5"
LINE = "#BCD3CB"
BLUE = "#DCEAF0"
def font(size: int, semibold: bool = False) -> ImageFont.FreeTypeFont:
name = "seguisb.ttf" if semibold else "segoeui.ttf"
return ImageFont.truetype(str(Path("C:/Windows/Fonts") / name), size)
def draw_mark(draw: ImageDraw.ImageDraw, box: tuple[int, int, int, int]) -> None:
left, top, right, bottom = box
width = right - left
height = bottom - top
map_points = [
(left + 0.04 * width, top + 0.30 * height),
(left + 0.32 * width, top + 0.18 * height),
(left + 0.64 * width, top + 0.30 * height),
(left + 0.94 * width, top + 0.18 * height),
(left + 0.94 * width, top + 0.76 * height),
(left + 0.64 * width, top + 0.88 * height),
(left + 0.32 * width, top + 0.76 * height),
(left + 0.04 * width, top + 0.88 * height),
]
draw.polygon(map_points, fill=PAPER, outline="#E1ECE5", width=max(4, width // 38))
draw.line(
[(left + 0.32 * width, top + 0.18 * height), (left + 0.32 * width, top + 0.76 * height)],
fill=GREEN_LIGHT,
width=max(4, width // 35),
)
draw.line(
[(left + 0.64 * width, top + 0.30 * height), (left + 0.64 * width, top + 0.88 * height)],
fill=GREEN_LIGHT,
width=max(4, width // 35),
)
cx = left + 0.50 * width
cy = top + 0.36 * height
radius = 0.20 * width
pin = [
(cx, cy + radius * 1.72),
(cx - radius * 0.86, cy + radius * 0.20),
(cx - radius, cy - radius * 0.18),
(cx - radius * 0.72, cy - radius * 0.72),
(cx - radius * 0.22, cy - radius),
(cx + radius * 0.22, cy - radius),
(cx + radius * 0.72, cy - radius * 0.72),
(cx + radius, cy - radius * 0.18),
(cx + radius * 0.86, cy + radius * 0.20),
]
draw.polygon(pin, fill=ORANGE)
draw.ellipse(
(cx - radius, cy - radius, cx + radius, cy + radius),
fill=ORANGE,
outline="white",
width=max(5, width // 32),
)
hole = radius * 0.34
draw.ellipse((cx - hole, cy - hole, cx + hole, cy + hole), fill="white")
def create_icon() -> None:
image = Image.new("RGB", (512, 512), GREEN)
draw = ImageDraw.Draw(image)
draw_mark(draw, (82, 78, 430, 434))
image.save(OUTPUT / "play-store-icon-512.png", optimize=True)
def create_feature_graphic() -> None:
image = Image.new("RGB", (1024, 500), "#F3F7F5")
draw = ImageDraw.Draw(image)
draw.rectangle((0, 0, 20, 500), fill=GREEN)
draw.rectangle((20, 0, 32, 500), fill=ORANGE)
draw.text((78, 107), "LME", font=font(34, True), fill=ORANGE)
draw.text((78, 154), "Mappe Catastali Pro", font=font(55, True), fill=INK)
draw.text((80, 234), "Mappe, GPS e progetti GIS", font=font(27), fill=GREEN)
draw.line((80, 290, 455, 290), fill=LINE, width=3)
draw.text((80, 315), "Consulta • misura • organizza", font=font(21), fill="#46635D")
panel = (595, 48, 965, 452)
draw.rounded_rectangle(panel, radius=8, fill="white", outline=LINE, width=3)
draw.polygon([(618, 86), (760, 65), (802, 164), (664, 190)], fill=BLUE, outline=GREEN_LIGHT)
draw.polygon([(806, 75), (940, 110), (923, 236), (784, 205)], fill="#E9EFE7", outline=GREEN_LIGHT)
draw.polygon([(625, 210), (779, 184), (817, 318), (665, 351)], fill="#F4E9D9", outline=GREEN_LIGHT)
draw.polygon([(820, 232), (929, 256), (946, 394), (853, 420), (798, 336)], fill=BLUE, outline=GREEN_LIGHT)
for x1, y1, x2, y2 in [
(630, 128, 932, 327),
(646, 310, 915, 128),
(704, 73, 857, 422),
(607, 267, 948, 181),
]:
draw.line((x1, y1, x2, y2), fill="#A4BDB5", width=3)
draw_mark(draw, (706, 136, 883, 340))
image.save(OUTPUT / "feature-graphic-1024x500.png", optimize=True)
def create_store_screenshot(raw_name: str, output_name: str, title: str, subtitle: str) -> None:
raw = Image.open(OUTPUT / raw_name).convert("RGB")
# Remove the Windows title bar and the desktop-only watermark/status area.
app_view = raw.crop((0, 32, raw.width, min(raw.height, 500)))
max_width, max_height = 1840, 760
scale = min(max_width / app_view.width, max_height / app_view.height)
app_view = app_view.resize(
(round(app_view.width * scale), round(app_view.height * scale)),
Image.Resampling.LANCZOS,
)
image = Image.new("RGB", (1920, 1080), "#F3F7F5")
draw = ImageDraw.Draw(image)
draw.rectangle((0, 0, 24, 1080), fill=GREEN)
draw.rectangle((24, 0, 38, 1080), fill=ORANGE)
draw.text((88, 54), title, font=font(52, True), fill=INK)
draw.text((90, 126), subtitle, font=font(26), fill="#46635D")
x = (1920 - app_view.width) // 2
y = 270
draw.rounded_rectangle(
(x - 8, y - 8, x + app_view.width + 8, y + app_view.height + 8),
radius=8,
fill="white",
outline=LINE,
width=4,
)
image.paste(app_view, (x, y))
image.save(OUTPUT / output_name, optimize=True)
def main() -> None:
OUTPUT.mkdir(exist_ok=True)
create_icon()
create_feature_graphic()
screenshots = [
(
"windows-map-raw.jpg",
"phone-01-map-1920x1080.png",
"Mappe catastali e cartografia",
"Consulta il territorio, cerca localita e lavora sulla mappa.",
),
(
"windows-data-drawings-raw.jpg",
"phone-02-data-drawings-1920x1080.png",
"Importa dati e disegna",
"KML, KMZ e GeoJSON insieme a misure e strumenti GIS.",
),
(
"windows-projects-raw.jpg",
"phone-03-projects-1920x1080.png",
"Organizza i tuoi progetti",
"Salva, riapri e condividi il lavoro sul campo.",
),
]
for raw_name, output_name, title, subtitle in screenshots:
if (OUTPUT / raw_name).exists():
create_store_screenshot(raw_name, output_name, title, subtitle)
if __name__ == "__main__":
main()