Files
mtga-assistant/packaging/make_icon.py
T
Aeth3randClaude Opus 5.5 fb6220155c Use the new app icon
The icon now comes from images/mtga-assistant-icon.png: make_icon.py
copies it into the package (window, taskbar and tray icon) and builds
the Windows .ico used for the .exe. The old generated SVG icon is gone.
The PyInstaller spec also keeps QtNetwork, needed for single-instance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 09:54:08 -04:00

54 lines
1.9 KiB
Python

"""Build the app icons from images/mtga-assistant-icon.png (the single source image).
Writes:
* src/mtga_assistant/icon.png: loaded at runtime for the window, taskbar and tray icon.
* images/mtga-assistant-icon.ico: the Windows .exe icon (PNG-compressed entries at the usual sizes).
Run after changing the source image: uv run python packaging/make_icon.py
"""
import shutil
import struct
import sys
from pathlib import Path
from PySide6.QtCore import QBuffer, QByteArray, QIODevice, Qt
from PySide6.QtGui import QGuiApplication, QImage
SIZES = [16, 24, 32, 48, 64, 128, 256]
ROOT = Path(__file__).resolve().parent.parent
SOURCE = ROOT / "images" / "mtga-assistant-icon.png"
def png_at(img: QImage, size: int) -> bytes:
scaled = img.scaled(size, size, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)
data = QByteArray()
buf = QBuffer(data)
buf.open(QIODevice.OpenModeFlag.WriteOnly)
scaled.save(buf, "PNG") # type: ignore[arg-type] # PySide accepts str; its stubs say bytes
return data.data()
def main() -> None:
QGuiApplication(sys.argv[:1])
img = QImage(str(SOURCE))
if img.isNull():
sys.exit(f"can't read {SOURCE}")
pngs = [(size, png_at(img, size)) for size in SIZES]
# ICONDIR header, one ICONDIRENTRY per image, then the PNG data.
out = struct.pack("<HHH", 0, 1, len(pngs))
offset = 6 + 16 * len(pngs)
for size, png in pngs:
dim = 0 if size >= 256 else size # 0 means 256
out += struct.pack("<BBBBHHII", dim, dim, 0, 0, 1, 32, len(png), offset)
offset += len(png)
out += b"".join(png for _, png in pngs)
ico = SOURCE.with_suffix(".ico")
ico.write_bytes(out)
shutil.copyfile(SOURCE, ROOT / "src" / "mtga_assistant" / "icon.png")
print(f"wrote {ico.relative_to(ROOT)} and src/mtga_assistant/icon.png from {SOURCE.relative_to(ROOT)}")
if __name__ == "__main__":
main()