""" Archetype: First Spark - App Icon Generator 1024x1024 PNG 앱 아이콘 생성 스크립트 주 색상: #FF6B35 (불꽃-주황) """ from PIL import Image, ImageDraw, ImageFilter import math def hex_to_rgb(hex_color): hex_color = hex_color.lstrip('#') return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4)) def create_app_icon(size=1024, output_path="app-icon.png"): img = Image.new('RGBA', (size, size), (0, 0, 0, 0)) draw = ImageDraw.Draw(img) # === 배경: 깊은 다크 네이비 → 다크 퍼플 그라디언트 === bg = Image.new('RGBA', (size, size)) bg_draw = ImageDraw.Draw(bg) for y in range(size): t = y / size # #0D0D1A (top) → #1A0A2E (bottom) r = int(13 + (26 - 13) * t) g = int(13 + (10 - 13) * t) b = int(26 + (46 - 26) * t) bg_draw.line([(0, y), (size, y)], fill=(r, g, b, 255)) img = Image.alpha_composite(img, bg) draw = ImageDraw.Draw(img) cx, cy = size // 2, size // 2 # === 외곽 글로우 링 (주황빛 오라) === glow_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0)) glow_draw = ImageDraw.Draw(glow_layer) for i in range(12, 0, -1): alpha = int(15 * (i / 12)) radius = int(size * 0.42) + i * 8 glow_draw.ellipse( [cx - radius, cy - radius, cx + radius, cy + radius], fill=(255, 107, 53, alpha) ) img = Image.alpha_composite(img, glow_layer) draw = ImageDraw.Draw(img) # === 메인 원형 배경 (진한 그라디언트 구체) === circle_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0)) circle_draw = ImageDraw.Draw(circle_layer) base_r = int(size * 0.42) for i in range(base_r, 0, -1): t = 1 - (i / base_r) # 어두운 중심부에서 불꽃 주황으로 r = int(20 + (120 - 20) * (1 - t**2)) g = int(8 + (40 - 8) * (1 - t**2)) b = int(35 + (15 - 35) * (1 - t**2)) circle_draw.ellipse( [cx - i, cy - i, cx + i, cy + i], fill=(r, g, b, 255) ) img = Image.alpha_composite(img, circle_layer) draw = ImageDraw.Draw(img) # === 불꽃 파티클 (배경 장식) === spark_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0)) spark_draw = ImageDraw.Draw(spark_layer) sparks = [ (cx - 180, cy - 200, 6, 180), (cx + 200, cy - 160, 5, 160), (cx - 220, cy + 100, 4, 140), (cx + 180, cy + 180, 5, 150), (cx - 60, cy - 280, 7, 200), (cx + 80, cy - 260, 6, 180), (cx - 260, cy - 40, 4, 130), (cx + 260, cy - 60, 5, 150), (cx - 100, cy + 270, 6, 160), (cx + 120, cy + 260, 4, 140), ] for sx, sy, sr, alpha in sparks: for gi in range(sr, 0, -1): ga = int(alpha * (gi / sr) ** 2) spark_draw.ellipse( [sx - gi, sy - gi, sx + gi, sy + gi], fill=(255, 180, 80, ga) ) img = Image.alpha_composite(img, spark_layer) draw = ImageDraw.Draw(img) # === 중앙 불꽃 형상 (메인 심볼) === flame_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0)) flame_draw = ImageDraw.Draw(flame_layer) # 불꽃 외형 (여러 레이어로 깊이 표현) # 레이어 1: 큰 불꽃 (오렌지-레드) flame1 = [ (cx, cy - 270), # 꼭대기 (cx + 120, cy - 140), # 오른쪽 상단 (cx + 160, cy + 30), # 오른쪽 중간 (cx + 90, cy + 200), # 오른쪽 하단 (cx, cy + 240), # 바닥 중앙 (cx - 90, cy + 200), # 왼쪽 하단 (cx - 160, cy + 30), # 왼쪽 중간 (cx - 120, cy - 140), # 왼쪽 상단 ] flame_draw.polygon(flame1, fill=(255, 90, 20, 230)) # 레이어 2: 중간 불꽃 (밝은 오렌지) flame2 = [ (cx, cy - 220), (cx + 90, cy - 100), (cx + 120, cy + 40), (cx + 60, cy + 180), (cx, cy + 200), (cx - 60, cy + 180), (cx - 120, cy + 40), (cx - 90, cy - 100), ] flame_draw.polygon(flame2, fill=(255, 140, 40, 220)) # 레이어 3: 내부 불꽃 (밝은 노란 오렌지) flame3 = [ (cx, cy - 160), (cx + 60, cy - 60), (cx + 80, cy + 60), (cx + 35, cy + 150), (cx, cy + 160), (cx - 35, cy + 150), (cx - 80, cy + 60), (cx - 60, cy - 60), ] flame_draw.polygon(flame3, fill=(255, 200, 80, 210)) # 레이어 4: 핵심 (흰색-노란색 빛) flame4 = [ (cx, cy - 80), (cx + 30, cy - 20), (cx + 40, cy + 50), (cx, cy + 80), (cx - 40, cy + 50), (cx - 30, cy - 20), ] flame_draw.polygon(flame4, fill=(255, 240, 180, 200)) # 중심 빛 (흰색 글로우) for i in range(30, 0, -1): alpha = int(180 * (i / 30) ** 2) flame_draw.ellipse( [cx - i, cy + 10 - i, cx + i, cy + 10 + i], fill=(255, 255, 240, alpha) ) # 불꽃 블러 (부드럽게) flame_blurred = flame_layer.filter(ImageFilter.GaussianBlur(radius=3)) img = Image.alpha_composite(img, flame_blurred) draw = ImageDraw.Draw(img) # === 원소 심볼 (아크 형태의 빛나는 링) === arc_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0)) arc_draw = ImageDraw.Draw(arc_layer) # 4개의 원소 호 (불, 물, 바람, 땅 의미) ring_r = int(size * 0.35) element_colors = [ (255, 80, 20, 180), # 불 (60, 160, 255, 160), # 물 (160, 240, 120, 140), # 바람 (200, 160, 60, 150), # 땅 ] for i, color in enumerate(element_colors): start_angle = i * 90 - 30 end_angle = start_angle + 60 for w in range(6, 0, -1): arc_draw.arc( [cx - ring_r - w, cy - ring_r - w, cx + ring_r + w, cy + ring_r + w], start=start_angle, end=end_angle, fill=(*color[:3], int(color[3] * w / 6)), width=w * 2 ) arc_blurred = arc_layer.filter(ImageFilter.GaussianBlur(radius=2)) img = Image.alpha_composite(img, arc_blurred) draw = ImageDraw.Draw(img) # === 상단 광택 효과 (입체감) === gloss_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0)) gloss_draw = ImageDraw.Draw(gloss_layer) gloss_r = int(size * 0.38) gloss_draw.ellipse( [cx - gloss_r, cy - gloss_r, cx + gloss_r, cy - gloss_r // 3], fill=(255, 255, 255, 25) ) gloss_blurred = gloss_layer.filter(ImageFilter.GaussianBlur(radius=20)) img = Image.alpha_composite(img, gloss_blurred) # === 저장 === final = img.convert('RGBA') final.save(output_path, 'PNG', optimize=True) print(f"[OK] 아이콘 저장: {output_path} ({size}x{size}px)") return final # 1024x1024 메인 아이콘 create_app_icon(1024, "C:/Users/jaeoh/Desktop/workspace/Archetype-FirstSpark/app-icon.png") # 512x512 앱스토어용 icon_1024 = Image.open("C:/Users/jaeoh/Desktop/workspace/Archetype-FirstSpark/app-icon.png") icon_512 = icon_1024.resize((512, 512), Image.LANCZOS) icon_512.save("C:/Users/jaeoh/Desktop/workspace/Archetype-FirstSpark/app-icon-512.png", 'PNG', optimize=True) print("[OK] 512x512 앱스토어용 저장 완료")