generate_icon_variants.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. """Generate 10 color variants of the MixBoard icon for iOS alternate icons."""
  2. from PIL import Image, ImageEnhance
  3. import numpy as np
  4. import os
  5. SRC = "/Users/vdrobkov/Misc/Documents/Copilot/MixBoard/Assets.xcassets/AppIcon.appiconset/icon_1024.png"
  6. OUT_DIR = "/Users/vdrobkov/Misc/Documents/Copilot/Mixboard iOS/Sources/Resources/Assets.xcassets"
  7. # Load source icon
  8. src = Image.open(SRC).convert("RGBA")
  9. pixels = np.array(src, dtype=np.float32)
  10. # The green accent color in the original is approximately (80, 190, 60)
  11. # We'll shift the hue of green pixels to create variants
  12. # 10 colors across the spectrum
  13. COLORS = {
  14. "Green": (0.35, 0.85, 0.25), # original
  15. "Lime": (0.55, 0.95, 0.15),
  16. "Cyan": (0.15, 0.85, 0.85),
  17. "Blue": (0.25, 0.45, 0.95),
  18. "Purple": (0.6, 0.3, 0.9),
  19. "Pink": (0.95, 0.3, 0.6),
  20. "Red": (0.95, 0.25, 0.25),
  21. "Orange": (0.95, 0.55, 0.15),
  22. "Gold": (0.95, 0.8, 0.15),
  23. "White": (0.9, 0.9, 0.92),
  24. }
  25. def recolor_icon(src_pixels, target_rgb):
  26. """Replace green-ish pixels with the target color, keeping brightness."""
  27. result = src_pixels.copy()
  28. r, g, b, a = result[:,:,0], result[:,:,1], result[:,:,2], result[:,:,3]
  29. # Detect green-dominant pixels (the accent color)
  30. # Green channel is significantly higher than red and blue
  31. green_mask = (g > r * 1.2) & (g > b * 1.2) & (g > 80)
  32. # Also include bright green pixels
  33. bright_green = (g > 100) & (g > r) & (g > b)
  34. mask = green_mask | bright_green
  35. # Calculate brightness of original green pixels
  36. brightness = g[mask] / 255.0
  37. # Apply new color with same brightness
  38. tr, tg, tb = target_rgb
  39. result[:,:,0][mask] = np.clip(brightness * tr * 255, 0, 255)
  40. result[:,:,1][mask] = np.clip(brightness * tg * 255, 0, 255)
  41. result[:,:,2][mask] = np.clip(brightness * tb * 255, 0, 255)
  42. return result
  43. for name, color in COLORS.items():
  44. recolored = recolor_icon(pixels, color)
  45. img = Image.fromarray(recolored.astype(np.uint8), "RGBA")
  46. # Save as alternate icon
  47. icon_dir = os.path.join(OUT_DIR, f"AppIcon-{name}.appiconset")
  48. os.makedirs(icon_dir, exist_ok=True)
  49. img.save(os.path.join(icon_dir, "icon_1024.png"), "PNG")
  50. # Write Contents.json
  51. with open(os.path.join(icon_dir, "Contents.json"), "w") as f:
  52. f.write('''{
  53. "images" : [
  54. { "filename" : "icon_1024.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" }
  55. ],
  56. "info" : {
  57. "author" : "xcode",
  58. "version" : 1
  59. }
  60. }''')
  61. print(f"Generated: {name} → {icon_dir}")
  62. print(f"\nDone! {len(COLORS)} icon variants generated.")