1.安装第三方库
我的是.NET6,因此需要安装8.0.0版本的【System.Drawing.Common】,若版本太高会在.NET6平台跑不了


2.代码
cs
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace PngToIcoConverter
{
class Program
{
static void Main(string[] args)
{
// 你的PNG和ICO文件路径
string pngFilePath = @"F:\C_program\MSSQLBackUpTools\WinFormsApp1\WinFormsApp1\pics\backup.png";
string icoOutputPath = @"F:\C_program\MSSQLBackUpTools\WinFormsApp1\WinFormsApp1\pics\backup.ico";
try
{
// 调用转换方法
ConvertPngToIco(pngFilePath, icoOutputPath);
Console.WriteLine("PNG转换为ICO成功!");
}
catch (FileNotFoundException ex)
{
Console.WriteLine($"错误:找不到文件 - {ex.Message}");
}
catch (IOException ex)
{
Console.WriteLine($"文件操作错误:{ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"转换失败:{ex.Message}");
}
}
/// <summary>
/// 将PNG图片转换为ICO图标(包含多尺寸:16x16, 32x32, 48x48)
/// </summary>
/// <param name="pngPath">PNG文件路径</param>
/// <param name="icoPath">ICO输出路径</param>
public static void ConvertPngToIco(string pngPath, string icoPath)
{
// 验证输入文件是否存在
if (!File.Exists(pngPath))
{
throw new FileNotFoundException("PNG源文件不存在", pngPath);
}
// 读取PNG图片
using (Bitmap pngBitmap = new Bitmap(pngPath))
{
// 定义ICO需要的256尺寸
int[] icoSizes = new[] { 256 };
using (MemoryStream ms = new MemoryStream())
{
// 创建ICO文件的编码器
IconEncoder encoder = new IconEncoder();
foreach (int size in icoSizes)
{
// 缩放图片到指定尺寸(保持比例)
using (Bitmap sizedBitmap = ResizeBitmap(pngBitmap, size, size))
{
encoder.AddFrame(sizedBitmap);
}
}
// 将ICO数据写入文件
encoder.Save(ms);
File.WriteAllBytes(icoPath, ms.ToArray());
}
}
}
/// <summary>
/// 缩放Bitmap到指定尺寸(保持宽高比,居中裁剪)
/// </summary>
private static Bitmap ResizeBitmap(Bitmap original, int width, int height)
{
Bitmap resized = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(resized))
{
// 高质量缩放设置
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
// 计算居中绘制的位置
float scale = Math.Max((float)width / original.Width, (float)height / original.Height);
int newWidth = (int)(original.Width * scale);
int newHeight = (int)(original.Height * scale);
int x = (width - newWidth) / 2;
int y = (height - newHeight) / 2;
g.Clear(Color.Transparent); // 保留透明背景
g.DrawImage(original, x, y, newWidth, newHeight);
}
return resized;
}
}
// 辅助类:用于生成多尺寸ICO文件
public class IconEncoder : IDisposable
{
private MemoryStream _stream = new MemoryStream();
private BinaryWriter _writer;
private int _imageCount = 0;
private List<byte[]> _imageData = new List<byte[]>();
public IconEncoder()
{
_writer = new BinaryWriter(_stream);
}
public void AddFrame(Bitmap bitmap)
{
if (bitmap.Width > 256 || bitmap.Height > 256)
throw new ArgumentException("图标尺寸不能超过256x256");
_imageCount++;
using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms, ImageFormat.Png);
_imageData.Add(ms.ToArray());
}
}
public void Save(Stream stream)
{
// 写入ICO文件头
_writer.Write((short)0); // 保留
_writer.Write((short)1); // ICO类型
_writer.Write((short)_imageCount); // 图像数量
long offset = 6 + 16 * _imageCount;
for (int i = 0; i < _imageCount; i++)
{
byte[] data = _imageData[i];
int width = data.Length > 0 ? new Bitmap(new MemoryStream(data)).Width : 0;
int height = data.Length > 0 ? new Bitmap(new MemoryStream(data)).Height : 0;
_writer.Write((byte)(width == 256 ? 0 : width));
_writer.Write((byte)(height == 256 ? 0 : height));
_writer.Write((byte)0); // 颜色数(0表示真彩色)
_writer.Write((byte)0); // 保留
_writer.Write((short)1); // 调色板
_writer.Write((short)32); // 位深度
_writer.Write(data.Length); // 图像数据大小
_writer.Write((int)offset); // 图像数据偏移量
offset += data.Length;
}
foreach (byte[] data in _imageData)
{
_writer.Write(data);
}
_stream.Seek(0, SeekOrigin.Begin);
_stream.CopyTo(stream);
}
public void Dispose()
{
_writer?.Dispose();
_stream?.Dispose();
}
}
}
3.Winform嵌入Icon

