using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; // 다이아몬드 픽셀 아이콘 생성기 v4 // 보석 다이아몬드 컷 실루엣 (flat top → wide girdle → bottom point) // 내부 facet 선 + RGBG 4색 채움 // 참고: Samsung Diamond Pixel 구조 (흰색선 다이아몬드 도형) var outputPath = args.Length > 0 ? args[0] : Path.Combine(AppContext.BaseDirectory, "icon.ico"); int[] sizes = [16, 24, 32, 48, 64, 128, 256]; var pngList = new List(); foreach (var sz in sizes) { using var bmp = DrawGemDiamond(sz); using var ms = new MemoryStream(); bmp.Save(ms, ImageFormat.Png); pngList.Add(ms.ToArray()); Console.WriteLine($" {sz}x{sz} OK"); } CreateIco(pngList, sizes, outputPath); Console.WriteLine($"Icon saved: {outputPath}"); static Bitmap DrawGemDiamond(int size) { var bmp = new Bitmap(size, size, PixelFormat.Format32bppArgb); using var g = Graphics.FromImage(bmp); g.SmoothingMode = SmoothingMode.HighQuality; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.Clear(Color.Transparent); float s = size; float cx = s / 2f; // ── 보석 다이아몬드 외곽 좌표 ── // Table (평평한 윗면) float tableL = s * 0.22f; float tableR = s * 0.78f; float tableY = s * 0.18f; // Girdle (가장 넓은 부분) float girdleL = s * 0.06f; float girdleR = s * 0.94f; float girdleY = s * 0.40f; // Culet (바닥 뾰족한 점) float culetX = cx; float culetY = s * 0.92f; // 주요 꼭짓점 PointF TL = new(tableL, tableY); // 테이블 좌 PointF TR = new(tableR, tableY); // 테이블 우 PointF GL = new(girdleL, girdleY); // 거들 좌 PointF GR = new(girdleR, girdleY); // 거들 우 PointF BT = new(culetX, culetY); // 바닥 점 // Crown 내부 포인트 (table → girdle 사이 facet) PointF CM = new(cx, girdleY); // 거들 중앙 PointF CT = new(cx, tableY); // 테이블 중앙 // Crown facet 분할점 PointF CL = new(s * 0.14f, girdleY); // 거들 좌측 근처 PointF CR = new(s * 0.86f, girdleY); // 거들 우측 근처 // Pavilion facet 내부 교차점들 float pavMidY = s * 0.62f; PointF PL = new(s * 0.28f, pavMidY); // 파빌리온 좌 중간 PointF PR = new(s * 0.72f, pavMidY); // 파빌리온 우 중간 PointF PM = new(cx, pavMidY); // 파빌리온 중앙 // ── 색상 ── var blue = Color.FromArgb(50, 110, 230); var blueBright = Color.FromArgb(80, 150, 255); var green = Color.FromArgb(60, 200, 80); var greenBright = Color.FromArgb(100, 235, 110); var red = Color.FromArgb(230, 50, 65); var redBright = Color.FromArgb(255, 90, 100); var greenDk = Color.FromArgb(45, 170, 75); var greenDkBr = Color.FromArgb(80, 210, 100); // ── Crown (상단부) 채우기 ── // Crown 좌: Blue FillPoly(g, new[]{TL, GL, CM, CT}, blueBright, blue); // Crown 우: Green FillPoly(g, new[]{TR, CT, CM, GR}, greenBright, green); // ── Pavilion (하단부) 채우기 ── // Pavilion 좌: Red FillPoly(g, new[]{GL, CM, BT}, redBright, red); // Pavilion 우: Green (darker) FillPoly(g, new[]{CM, GR, BT}, greenDkBr, greenDk); // ── Facet 내부 색상 변화 (깊이감) ── // Crown 좌측 어두운 삼각형 using var crownShadow = new SolidBrush(Color.FromArgb(25, 0, 0, 0)); g.FillPolygon(crownShadow, new[]{TL, GL, new PointF(cx * 0.7f, girdleY * 0.85f)}); // Pavilion 중앙 밝은 삼각형 (반사) using var pavHighlight = new SolidBrush(Color.FromArgb(20, 255, 255, 255)); g.FillPolygon(pavHighlight, new[]{CM, BT, new PointF(cx - s*0.08f, pavMidY)}); // ── Facet 선 (흰색) ── float lw = Math.Max(0.8f, s / 140f); using var facetPen = new Pen(Color.FromArgb(180, 255, 255, 255), lw) { LineJoin = LineJoin.Round, StartCap = LineCap.Round, EndCap = LineCap.Round }; // Crown facet lines // 테이블 윗변 g.DrawLine(facetPen, TL, TR); // 테이블 → 거들 대각선 g.DrawLine(facetPen, TL, GL); g.DrawLine(facetPen, TR, GR); // 세로 중심선 (table → girdle) g.DrawLine(facetPen, CT, CM); // Crown 크로스 facet g.DrawLine(facetPen, TL, CM); g.DrawLine(facetPen, TR, CM); // 추가 Crown facet (table 모서리 → 거들 중간) g.DrawLine(facetPen, TL, new PointF(girdleL + (cx - girdleL) * 0.5f, girdleY)); g.DrawLine(facetPen, TR, new PointF(cx + (girdleR - cx) * 0.5f, girdleY)); // Girdle 수평선 g.DrawLine(facetPen, GL, GR); // Pavilion facet lines // 거들 → 바닥 점 g.DrawLine(facetPen, GL, BT); g.DrawLine(facetPen, GR, BT); // 중심 → 바닥 g.DrawLine(facetPen, CM, BT); // Pavilion 크로스 facets float crossY = girdleY + (culetY - girdleY) * 0.45f; PointF crossL = new(girdleL + (culetX - girdleL) * 0.45f, crossY); PointF crossR = new(girdleR - (girdleR - culetX) * 0.45f, crossY); g.DrawLine(facetPen, GL, crossR); g.DrawLine(facetPen, GR, crossL); // 거들 중간점에서 바닥으로 g.DrawLine(facetPen, new PointF(girdleL + (cx - girdleL) * 0.5f, girdleY), BT); g.DrawLine(facetPen, new PointF(cx + (girdleR - cx) * 0.5f, girdleY), BT); // ── 외곽선 (두꺼운 흰색) ── float olw = Math.Max(1.2f, s / 100f); using var outlinePen = new Pen(Color.FromArgb(220, 255, 255, 255), olw) { LineJoin = LineJoin.Round }; g.DrawPolygon(outlinePen, new[]{TL, TR, GR, BT, GL}); // ── 상단 하이라이트 (테이블 면 빛 반사) ── using var tableHL = new LinearGradientBrush( TL, new PointF(cx, girdleY), Color.FromArgb(45, 255, 255, 255), Color.Transparent); g.FillPolygon(tableHL, new[]{TL, TR, CT}); return bmp; } static void FillPoly(Graphics g, PointF[] pts, Color c1, Color c2) { float minX = pts.Min(p => p.X), maxX = pts.Max(p => p.X); float minY = pts.Min(p => p.Y), maxY = pts.Max(p => p.Y); var rect = new RectangleF(minX, minY, Math.Max(1, maxX - minX), Math.Max(1, maxY - minY)); try { using var brush = new LinearGradientBrush(rect, c1, c2, LinearGradientMode.Vertical); g.FillPolygon(brush, pts); } catch { using var brush = new SolidBrush(c1); g.FillPolygon(brush, pts); } } static void CreateIco(List pngs, int[] sizes, string path) { using var ms = new MemoryStream(); using var bw = new BinaryWriter(ms); bw.Write((short)0); bw.Write((short)1); bw.Write((short)pngs.Count); int offset = 6 + 16 * pngs.Count; for (int i = 0; i < pngs.Count; i++) { byte dim = (byte)(sizes[i] >= 256 ? 0 : sizes[i]); bw.Write(dim); bw.Write(dim); bw.Write((byte)0); bw.Write((byte)0); bw.Write((short)1); bw.Write((short)32); bw.Write(pngs[i].Length); bw.Write(offset); offset += pngs[i].Length; } foreach (var png in pngs) bw.Write(png); File.WriteAllBytes(path, ms.ToArray()); }