// C# Script: 다이아몬드 픽셀 아이콘 생성 (PNG → ICO) // 실행: dotnet-script GenerateIcon.csx // 또는 별도 콘솔 앱으로 빌드 using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; // 여러 크기로 생성 int[] sizes = { 16, 24, 32, 48, 64, 128, 256 }; string outputDir = Path.Combine(Path.GetDirectoryName(Environment.ProcessPath) ?? ".", "output"); Directory.CreateDirectory(outputDir); foreach (var size in sizes) { using var bmp = DrawDiamondPixel(size); bmp.Save(Path.Combine(outputDir, $"icon_{size}.png"), ImageFormat.Png); Console.WriteLine($"Generated icon_{size}.png"); } // ICO 파일 생성 CreateIco(sizes.Select(s => Path.Combine(outputDir, $"icon_{s}.png")).ToArray(), Path.Combine(outputDir, "icon.ico")); Console.WriteLine("Generated icon.ico"); static Bitmap DrawDiamondPixel(int size) { var bmp = new Bitmap(size, size, PixelFormat.Format32bppArgb); using var g = Graphics.FromImage(bmp); g.SmoothingMode = SmoothingMode.HighQuality; g.Clear(Color.Transparent); float cx = size / 2f; float cy = size * 0.47f; // 약간 위쪽 중심 float w = size * 0.44f; // 좌우 반폭 float ht = size * 0.27f; // 상단 높이 float hb = size * 0.23f; // 하단 높이 // 꼭짓점 PointF top = new(cx, cy - ht); PointF right = new(cx + w, cy); PointF bottom = new(cx, cy + hb); PointF left = new(cx - w, cy); PointF center = new(cx, cy); // 좌상 - Blue using (var brush = new LinearGradientBrush(top, center, Color.FromArgb(91, 141, 239), Color.FromArgb(45, 95, 204))) { g.FillPolygon(brush, new[] { top, center, left }); } // 우상 - Green using (var brush = new LinearGradientBrush(top, center, Color.FromArgb(126, 217, 87), Color.FromArgb(76, 175, 80))) { g.FillPolygon(brush, new[] { top, right, center }); } // 좌하 - Red using (var brush = new LinearGradientBrush(left, bottom, Color.FromArgb(255, 77, 106), Color.FromArgb(229, 57, 53))) { g.FillPolygon(brush, new[] { left, center, bottom }); } // 우하 - Green (darker) using (var brush = new LinearGradientBrush(right, bottom, Color.FromArgb(102, 187, 106), Color.FromArgb(67, 160, 71))) { g.FillPolygon(brush, new[] { right, center, bottom }); } // 갭 라인 float gap = Math.Max(1, size / 128f); using var pen = new Pen(Color.FromArgb(200, 10, 10, 20), gap); g.DrawLine(pen, top, bottom); g.DrawLine(pen, left, right); // 외곽 하이라이트 float border = Math.Max(0.5f, size / 256f); using var borderPen = new Pen(Color.FromArgb(60, 255, 255, 255), border); g.DrawPolygon(borderPen, new[] { top, right, bottom, left }); return bmp; } static void CreateIco(string[] pngPaths, string icoPath) { using var ms = new MemoryStream(); using var bw = new BinaryWriter(ms); var pngData = pngPaths.Select(p => File.ReadAllBytes(p)).ToArray(); // ICO Header bw.Write((short)0); // Reserved bw.Write((short)1); // ICO type bw.Write((short)pngData.Length); // Image count int offset = 6 + (16 * pngData.Length); // After header + entries foreach (var png in pngData) { using var img = Image.FromStream(new MemoryStream(png)); bw.Write((byte)(img.Width >= 256 ? 0 : img.Width)); bw.Write((byte)(img.Height >= 256 ? 0 : img.Height)); bw.Write((byte)0); // Color palette bw.Write((byte)0); // Reserved bw.Write((short)1); // Color planes bw.Write((short)32); // Bits per pixel bw.Write(png.Length); // Size bw.Write(offset); // Offset offset += png.Length; } foreach (var png in pngData) bw.Write(png); File.WriteAllBytes(icoPath, ms.ToArray()); }