Files
AX-Copilot/tools/GenerateIcon.csx

116 lines
3.8 KiB
C#

// 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());
}