HartMobile/tools/process_screenshots.py
alexanderkaptsov 39662d323a HART Mobile v1.0.1 — initial clean commit
Android app for HART protocol field devices (Bluetooth SPP / USB CP210x).
Kotlin, MVVM, Jetpack Navigation, Material Design.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 23:23:18 +09:00

112 lines
4.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Обработка скриншотов для RuStore.
- Масштабирование до 1080x1920
- Добавление подписи сверху на синей полосе
- Вывод в PNG
"""
from PIL import Image, ImageDraw, ImageFont
import os
INPUT_DIR = os.path.join(os.path.dirname(__file__), '..', 'temp_screenshots')
OUTPUT_DIR = os.path.join(os.path.dirname(__file__), '..', 'store_screenshots')
TARGET_W = 1080
TARGET_H = 1920
HEADER_H = 160 # высота полосы с подписью
HEADER_COLOR = (55, 71, 161) # синий как в приложении (#3747A1)
TEXT_COLOR = (255, 255, 255)
# Маппинг файлов → подписи (порядок по времени)
SCREENSHOTS = [
("photo_2026-03-17 23.08.50.jpeg", "Параметры устройства", "01_device.png"),
("photo_2026-03-17 23.08.49.jpeg", "Тренд температуры", "02_trend.png"),
("photo_2026-03-17 23.08.48.jpeg", "Loop Test", "03_loop_test.png"),
("photo_2026-03-17 23.08.47.jpeg", "Поиск устройств", "04_poll_scan.png"),
("photo_2026-03-17 23.08.45.jpeg", "Подключение", "05_scan.png"),
]
def find_font(size):
"""Ищем подходящий шрифт."""
font_paths = [
"/System/Library/Fonts/Helvetica.ttc",
"/System/Library/Fonts/SFNSDisplay.ttf",
"/System/Library/Fonts/Supplemental/Arial Bold.ttf",
"/System/Library/Fonts/Supplemental/Arial.ttf",
"/Library/Fonts/Arial Bold.ttf",
]
for p in font_paths:
if os.path.exists(p):
try:
return ImageFont.truetype(p, size)
except Exception:
continue
return ImageFont.load_default()
def process_screenshot(input_path, title, output_path):
img = Image.open(input_path).convert("RGB")
# Область для скриншота: TARGET_W x (TARGET_H - HEADER_H)
content_h = TARGET_H - HEADER_H
# Масштабируем скриншот, сохраняя пропорции, заполняя ширину
scale = TARGET_W / img.width
new_h = int(img.height * scale)
img_scaled = img.resize((TARGET_W, new_h), Image.LANCZOS)
# Обрезаем или центрируем по высоте
if new_h > content_h:
# Обрезаем снизу (статус-бар сверху важнее)
img_scaled = img_scaled.crop((0, 0, TARGET_W, content_h))
elif new_h < content_h:
# Центрируем на белом фоне
bg = Image.new("RGB", (TARGET_W, content_h), (255, 255, 255))
offset_y = (content_h - new_h) // 2
bg.paste(img_scaled, (0, offset_y))
img_scaled = bg
# Создаём итоговое изображение
result = Image.new("RGB", (TARGET_W, TARGET_H), (255, 255, 255))
# Рисуем шапку
draw = ImageDraw.Draw(result)
draw.rectangle([(0, 0), (TARGET_W, HEADER_H)], fill=HEADER_COLOR)
# Текст по центру шапки
font = find_font(48)
bbox = draw.textbbox((0, 0), title, font=font)
tw = bbox[2] - bbox[0]
th = bbox[3] - bbox[1]
tx = (TARGET_W - tw) // 2
ty = (HEADER_H - th) // 2
draw.text((tx, ty), title, fill=TEXT_COLOR, font=font)
# Вставляем скриншот под шапку
result.paste(img_scaled, (0, HEADER_H))
result.save(output_path, "PNG", optimize=True)
print(f" OK: {output_path} ({TARGET_W}x{TARGET_H})")
def main():
os.makedirs(OUTPUT_DIR, exist_ok=True)
print(f"RuStore screenshots → {OUTPUT_DIR}\n")
for filename, title, out_name in SCREENSHOTS:
input_path = os.path.join(INPUT_DIR, filename)
output_path = os.path.join(OUTPUT_DIR, out_name)
if not os.path.exists(input_path):
print(f" SKIP: {filename} not found")
continue
process_screenshot(input_path, title, output_path)
print(f"\nГотово! {len(SCREENSHOTS)} скриншотов обработано.")
if __name__ == "__main__":
main()