116 lines
3.8 KiB
C#
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());
|
|
}
|