151 lines
5.3 KiB
C#
151 lines
5.3 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Drawing.Imaging;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace TimerApp
|
|
{
|
|
public static class IconGenerator
|
|
{
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
private static extern bool DestroyIcon(IntPtr hIcon);
|
|
|
|
public static Icon GenerateClockIcon(int size = 64)
|
|
{
|
|
if (size < 16)
|
|
size = 16;
|
|
|
|
using (Bitmap bmp = new Bitmap(size, size))
|
|
using (Graphics g = Graphics.FromImage(bmp))
|
|
{
|
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
|
g.Clear(Color.Transparent);
|
|
|
|
DrawClock(g, size);
|
|
|
|
IntPtr hIcon = bmp.GetHicon();
|
|
try
|
|
{
|
|
using Icon icon = Icon.FromHandle(hIcon);
|
|
return (Icon)icon.Clone();
|
|
}
|
|
finally
|
|
{
|
|
DestroyIcon(hIcon);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void WriteClockIco(string filePath, int size = 256)
|
|
{
|
|
byte[] icoBytes = CreateClockIcoBytes(size);
|
|
File.WriteAllBytes(filePath, icoBytes);
|
|
}
|
|
|
|
private static byte[] CreateClockIcoBytes(int size)
|
|
{
|
|
if (size <= 0)
|
|
size = 256;
|
|
if (size > 256)
|
|
size = 256;
|
|
if (size < 16)
|
|
size = 16;
|
|
|
|
byte[] pngBytes;
|
|
using (Bitmap bmp = new Bitmap(size, size))
|
|
using (Graphics g = Graphics.FromImage(bmp))
|
|
{
|
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
|
g.Clear(Color.Transparent);
|
|
DrawClock(g, size);
|
|
|
|
using var ms = new MemoryStream();
|
|
bmp.Save(ms, ImageFormat.Png);
|
|
pngBytes = ms.ToArray();
|
|
}
|
|
|
|
using var icoStream = new MemoryStream(6 + 16 + pngBytes.Length);
|
|
using (var bw = new BinaryWriter(icoStream, System.Text.Encoding.UTF8, leaveOpen: true))
|
|
{
|
|
bw.Write((ushort)0);
|
|
bw.Write((ushort)1);
|
|
bw.Write((ushort)1);
|
|
|
|
bw.Write((byte)(size == 256 ? 0 : size));
|
|
bw.Write((byte)(size == 256 ? 0 : size));
|
|
bw.Write((byte)0);
|
|
bw.Write((byte)0);
|
|
bw.Write((ushort)1);
|
|
bw.Write((ushort)32);
|
|
bw.Write((uint)pngBytes.Length);
|
|
bw.Write((uint)(6 + 16));
|
|
}
|
|
|
|
icoStream.Write(pngBytes, 0, pngBytes.Length);
|
|
return icoStream.ToArray();
|
|
}
|
|
|
|
private static void DrawClock(Graphics g, int size)
|
|
{
|
|
int margin = Math.Max(2, size / 16);
|
|
int clockSize = size - margin * 2;
|
|
Rectangle rect = new Rectangle(margin, margin, clockSize, clockSize);
|
|
|
|
// 定义轮廓颜色和宽度
|
|
Color outlineColor = Color.FromArgb(64, 64, 64);
|
|
float mainWidth = Math.Max(2, size / 16f);
|
|
float outlineWidth = mainWidth + Math.Max(1, size / 32f);
|
|
float handWidth = Math.Max(2, size / 22f);
|
|
float handOutlineWidth = handWidth + Math.Max(1, size / 32f);
|
|
|
|
// 1. 绘制耳朵 (先画轮廓)
|
|
using (Pen outlinePen = new Pen(outlineColor, Math.Max(1, size / 32f)))
|
|
using (Brush earBrush = new SolidBrush(Color.White))
|
|
{
|
|
// 左耳
|
|
g.DrawPie(outlinePen, 0, 0, size / 2, size / 2, 200, 50);
|
|
g.FillPie(earBrush, 0, 0, size / 2, size / 2, 200, 50);
|
|
|
|
// 右耳
|
|
g.DrawPie(outlinePen, size / 2, 0, size / 2, size / 2, 290, 50);
|
|
g.FillPie(earBrush, size / 2, 0, size / 2, size / 2, 290, 50);
|
|
}
|
|
|
|
// 2. 绘制表盘外圈 (先画轮廓)
|
|
using (Pen outlinePen = new Pen(outlineColor, outlineWidth))
|
|
using (Pen pen = new Pen(Color.White, mainWidth))
|
|
using (Brush bgBrush = new SolidBrush(Color.Black))
|
|
{
|
|
// 填充表盘背景,确保浅色模式下也能看清
|
|
g.FillEllipse(bgBrush, rect);
|
|
g.DrawEllipse(outlinePen, rect);
|
|
g.DrawEllipse(pen, rect);
|
|
}
|
|
|
|
// 3. 绘制指针 (先画轮廓)
|
|
Point center = new Point(size / 2, size / 2);
|
|
Point handEnd1 = new Point(center.X + Math.Max(2, size * 10 / 64), center.Y - Math.Max(2, size * 10 / 64));
|
|
Point handEnd2 = new Point(center.X, center.Y - Math.Max(3, size * 18 / 64));
|
|
|
|
using (Pen outlinePen = new Pen(outlineColor, handOutlineWidth))
|
|
using (Pen handPen = new Pen(Color.LightGreen, handWidth))
|
|
{
|
|
outlinePen.EndCap = LineCap.Round;
|
|
outlinePen.StartCap = LineCap.Round;
|
|
handPen.EndCap = LineCap.Round;
|
|
handPen.StartCap = LineCap.Round;
|
|
|
|
// 指针1
|
|
g.DrawLine(outlinePen, center, handEnd1);
|
|
g.DrawLine(handPen, center, handEnd1);
|
|
|
|
// 指针2
|
|
g.DrawLine(outlinePen, center, handEnd2);
|
|
g.DrawLine(handPen, center, handEnd2);
|
|
}
|
|
}
|
|
}
|
|
}
|