#!/usr/bin/env python3 """ Atlas for Mac — App Icon Generator Brand: Calm Authority Concept: A stylized globe with meridian lines overlaid on a deep-teal-to-emerald gradient, with a darker premium backdrop and a refined mint accent arc representing the "atlas" mapping metaphor. Generates all required macOS app icon sizes from a programmatic SVG. """ import subprocess import os import json import tempfile ICON_DIR = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "Apps", "AtlasApp", "Sources", "AtlasApp", "Assets.xcassets", "AppIcon.appiconset" ) # macOS icon sizes needed SIZES = [16, 32, 64, 128, 256, 512, 1024] def generate_svg(size=1024): """Generate the Atlas app icon as SVG.""" return f''' ''' def main(): os.makedirs(ICON_DIR, exist_ok=True) # Write SVG svg_content = generate_svg(1024) svg_path = os.path.join(ICON_DIR, "icon_1024.svg") with open(svg_path, "w") as f: f.write(svg_content) print(f"SVG written to {svg_path}") # Try to convert to PNG using sips (built-in macOS tool) via a temp file # First, check if we have rsvg-convert or cairosvg converters = [] # Check for rsvg-convert (from librsvg) if subprocess.run(["which", "rsvg-convert"], capture_output=True).returncode == 0: converters.append("rsvg-convert") # Check for python cairosvg try: import cairosvg converters.append("cairosvg") except ImportError: pass # Check for Inkscape if subprocess.run(["which", "inkscape"], capture_output=True).returncode == 0: converters.append("inkscape") images = {} if "rsvg-convert" in converters: print("Using rsvg-convert for PNG generation...") for s in SIZES: out = os.path.join(ICON_DIR, f"icon_{s}x{s}.png") subprocess.run([ "rsvg-convert", "-w", str(s), "-h", str(s), svg_path, "-o", out ], check=True) images[f"icon_{s}x{s}.png"] = s print(f" Generated {s}x{s}") elif "cairosvg" in converters: print("Using cairosvg for PNG generation...") import cairosvg for s in SIZES: out = os.path.join(ICON_DIR, f"icon_{s}x{s}.png") cairosvg.svg2png( bytestring=svg_content.encode(), write_to=out, output_width=s, output_height=s ) images[f"icon_{s}x{s}.png"] = s print(f" Generated {s}x{s}") elif "inkscape" in converters: print("Using Inkscape for PNG generation...") for s in SIZES: out = os.path.join(ICON_DIR, f"icon_{s}x{s}.png") subprocess.run([ "inkscape", svg_path, "--export-type=png", f"--export-filename={out}", f"--export-width={s}", f"--export-height={s}" ], check=True, capture_output=True) images[f"icon_{s}x{s}.png"] = s print(f" Generated {s}x{s}") else: print("WARNING: No SVG-to-PNG converter found.") print("Install one of: librsvg (brew install librsvg), cairosvg (pip install cairosvg), or Inkscape") print(f"Then run: cd {ICON_DIR} && rsvg-convert -w 1024 -h 1024 icon_1024.svg -o icon_1024x1024.png") print("SVG file is ready for manual conversion.") # Still write Contents.json with expected filenames for s in SIZES: images[f"icon_{s}x{s}.png"] = s # Write Contents.json for Xcode icon_images = [] for s in [16, 32, 128, 256, 512]: # 1x icon_images.append({ "filename": f"icon_{s}x{s}.png", "idiom": "mac", "scale": "1x", "size": f"{s}x{s}" }) # 2x icon_images.append({ "filename": f"icon_{s*2}x{s*2}.png", "idiom": "mac", "scale": "2x", "size": f"{s}x{s}" }) contents = { "images": icon_images, "info": { "author": "atlas-icon-generator", "version": 1 } } contents_path = os.path.join(ICON_DIR, "Contents.json") with open(contents_path, "w") as f: json.dump(contents, f, indent=2) print(f"Contents.json written to {contents_path}") print("Done!") if __name__ == "__main__": main()