| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- """Generate MixBoard iOS app icon — a stylized mixing board fader knob
- with a music note, on a dark gradient background."""
- from PIL import Image, ImageDraw, ImageFont
- import math
- SIZE = 1024
- CENTER = SIZE // 2
- img = Image.new("RGBA", (SIZE, SIZE), (0, 0, 0, 0))
- draw = ImageDraw.Draw(img)
- # Background — dark gradient with subtle green tint (Winamp vibes)
- for y in range(SIZE):
- t = y / SIZE
- r = int(10 + 15 * t)
- g = int(15 + 25 * t)
- b = int(12 + 18 * t)
- draw.line([(0, y), (SIZE, y)], fill=(r, g, b, 255))
- # Rounded corners mask
- mask = Image.new("L", (SIZE, SIZE), 0)
- mask_draw = ImageDraw.Draw(mask)
- radius = int(SIZE * 0.22)
- mask_draw.rounded_rectangle([(0, 0), (SIZE - 1, SIZE - 1)], radius=radius, fill=255)
- # Apply rounded corners
- img.putalpha(mask)
- # Outer glow ring
- ring_cx, ring_cy = CENTER, CENTER + 20
- ring_r_outer = 380
- ring_r_inner = 310
- for angle_deg in range(360):
- angle = math.radians(angle_deg)
- # Green glow gradient around the ring
- intensity = 0.6 + 0.4 * math.sin(angle * 2 + 0.5)
- g_val = int(200 * intensity)
- for r_offset in range(ring_r_inner, ring_r_outer):
- alpha_factor = 1.0 - abs(r_offset - (ring_r_inner + ring_r_outer) / 2) / ((ring_r_outer - ring_r_inner) / 2)
- alpha_factor = max(0, alpha_factor) ** 1.5
- x = int(ring_cx + r_offset * math.cos(angle))
- y = int(ring_cy + r_offset * math.sin(angle))
- if 0 <= x < SIZE and 0 <= y < SIZE:
- existing = img.getpixel((x, y))
- new_g = min(255, existing[1] + int(g_val * alpha_factor * 0.5))
- img.putpixel((x, y), (existing[0], new_g, existing[2], existing[3]))
- # Central knob (fader/mixing board aesthetic)
- knob_r = 260
- # Dark circle
- for y_off in range(-knob_r, knob_r + 1):
- for x_off in range(-knob_r, knob_r + 1):
- dist = math.sqrt(x_off ** 2 + y_off ** 2)
- if dist <= knob_r:
- x = ring_cx + x_off
- y = ring_cy + y_off
- if 0 <= x < SIZE and 0 <= y < SIZE:
- # Metallic gradient
- t = (y_off + knob_r) / (2 * knob_r)
- base = int(30 + 35 * (1 - t))
- # Edge highlight
- edge = max(0, 1 - (knob_r - dist) / 15) if dist > knob_r - 15 else 0
- highlight = int(80 * edge)
- r_val = min(255, base + highlight)
- g_val = min(255, base + highlight + int(20 * edge))
- b_val = min(255, base + highlight)
- img.putpixel((int(x), int(y)), (r_val, g_val, b_val, 255))
- # Knob indicator line (green, pointing up — like a fader position)
- line_w = 8
- for y_off in range(-knob_r + 30, -60):
- for x_off in range(-line_w, line_w + 1):
- x = ring_cx + x_off
- y = ring_cy + y_off
- if 0 <= x < SIZE and 0 <= y < SIZE:
- dist_from_center = abs(x_off)
- alpha = max(0, 1 - dist_from_center / line_w)
- g_val = int(255 * alpha)
- existing = img.getpixel((x, y))
- img.putpixel((x, y), (0, g_val, 0, 255))
- # Music note symbol in center
- # Draw a simple eighth note
- note_cx, note_cy = ring_cx + 10, ring_cy + 30
- note_color = (0, 220, 0, 255)
- # Note head (filled ellipse)
- head_rx, head_ry = 45, 35
- for y_off in range(-head_ry, head_ry + 1):
- for x_off in range(-head_rx, head_rx + 1):
- # Rotated ellipse
- angle = -0.4
- rx = x_off * math.cos(angle) - y_off * math.sin(angle)
- ry = x_off * math.sin(angle) + y_off * math.cos(angle)
- if (rx / head_rx) ** 2 + (ry / head_ry) ** 2 <= 1:
- x = note_cx + x_off
- y = note_cy + y_off
- if 0 <= x < SIZE and 0 <= y < SIZE:
- img.putpixel((int(x), int(y)), note_color)
- # Note stem
- stem_x = note_cx + 40
- for y_off in range(-160, 10):
- for x_off in range(-4, 5):
- x = stem_x + x_off
- y = note_cy + y_off
- if 0 <= x < SIZE and 0 <= y < SIZE:
- img.putpixel((int(x), int(y)), note_color)
- # Flag (curved)
- for i in range(60):
- t = i / 60
- fx = stem_x + int(35 * math.sin(t * math.pi * 0.8))
- fy = note_cy - 160 + int(60 * t)
- for dx in range(-3, 4):
- for dy in range(-2, 3):
- x, y = fx + dx, fy + dy
- if 0 <= x < SIZE and 0 <= y < SIZE:
- img.putpixel((x, y), note_color)
- # "MB" text at bottom
- # Use a simple approach — draw M and B with rectangles
- text_y = SIZE - 130
- text_color = (0, 180, 0, 200)
- # Just add a subtle "MixBoard" text feel with dots
- for i, char_x in enumerate(range(CENTER - 100, CENTER + 120, 22)):
- dot_r = 4
- for dy in range(-dot_r, dot_r + 1):
- for dx in range(-dot_r, dot_r + 1):
- if dx ** 2 + dy ** 2 <= dot_r ** 2:
- x, y = char_x + dx, text_y + dy
- if 0 <= x < SIZE and 0 <= y < SIZE:
- alpha = int(150 * (1 - (dx ** 2 + dy ** 2) / dot_r ** 2))
- existing = img.getpixel((x, y))
- img.putpixel((x, y), (0, min(255, existing[1] + alpha), 0, existing[3]))
- # Save
- output_path = "/Users/vdrobkov/Misc/Documents/Copilot/Mixboard iOS/Sources/Resources/Assets.xcassets/AppIcon.appiconset/icon_1024.png"
- img.save(output_path, "PNG")
- print(f"Icon saved to {output_path}")
- print(f"Size: {img.size}")
|