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

+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()