图片格式Png转Ico之System.Drawing与SixLabors.ImageSharp

System.Drawing 方式

/// <summary>
/// 将Png格式图片转为Ico格式
/// </summary>
/// <param name="imagePath">原图路径</param>
/// <param name="outPath">Ico图片保存地址</param>
/// <param name="size">图片转换目标尺寸</param>
/// <param name="preserveAspectRatio">是否保持原来的纵横比</param>
/// <returns></returns>
public static bool ConvertPNGToIcon(string imagePath, string outPath, int size = 16, bool preserveAspectRatio = false)
{
    System.Drawing.Image img = System.Drawing.Image.FromFile(imagePath);
    int width, height;
    if (preserveAspectRatio)
    {
        width = size;
        height = img.Height / img.Width * size;
    }
    else
    {
        width = height = size;
    }
    //调整大小
    Bitmap bitmap = new Bitmap(width, height);
    using (Graphics graphics = Graphics.FromImage(bitmap))
    {
        graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        graphics.DrawImage(img, 0, 0, width, height);
    }
    using (MemoryStream memoryStream = new MemoryStream())
    {
        bitmap.Save(memoryStream, ImageFormat.Png);//将原图读取为png格式并存入原图内存流
        return ConvertImageStreamIco(memoryStream, outPath, width, height);
    }
}

SixLabors.ImageSharp方式

/// <summary>
/// 将Png格式图片转为Ico格式
/// </summary>
/// <param name="imagePath">原图路径</param>
/// <param name="outPath">Ico图片保存地址</param>
/// <param name="size">图片转换目标尺寸</param>
/// <param name="preserveAspectRatio">是否保持原来的纵横比</param>
/// <returns></returns>
public static bool ConvertPNGToIconSIX(string imagePath, string outPath, int size = 16, bool preserveAspectRatio = false)
{
    using (Image<Rgba32> image = SixLabors.ImageSharp.Image.Load<Rgba32>(imagePath))
    {
        int width, height;
        //按原来的纵横比缩放到指定大小
        if (preserveAspectRatio)
        {
            width = size;
            height = image.Height / image.Width * size;
        }
        else
        {
            width = height = size;
        }
        image.Mutate(x => x.Resize(width, height));
        using (MemoryStream imageStream = new MemoryStream())
        {
            image.SaveAsPng(imageStream);//将原图片以Png格式存在内存流中
            imageStream.Position = 0;//将流的位置重置为开始 imageStream.Seek(0, SeekOrigin.Begin);
            return ConvertImageStreamIco(imageStream, outPath, width, height);
        }
    }
}

 

公共部分

转ico

 public static bool ConvertImageStreamIco(MemoryStream memoryStream, string outPath, int width, int height)
 {
     using (FileStream output = new FileStream(outPath, FileMode.OpenOrCreate))
     {
         BinaryWriter iconWriter = new BinaryWriter(output);
         if (output != null && iconWriter != null)
         {
             //根据原图信息,进行文件头写入
             // 0-1 reserved, 0
             // 0-1保留
             iconWriter.Write((byte)0);
             iconWriter.Write((byte)0);

             // 2-3 image type, 1 = icon, 2 = cursor
             //2-3文件类型。1 = 图标, 2 = 光标
             iconWriter.Write((short)1);

             // 4-5 number of images
             //4-5图像数量(图标可以包含多个图像)
             iconWriter.Write((short)1);

             // image entry 1
             // 0 image width
             //6图标宽度
             iconWriter.Write((byte)width);
             // 1 image height
             //7图标高度
             iconWriter.Write((byte)height);

             // 2 number of colors
             iconWriter.Write((byte)0);

             // 3 reserved

             iconWriter.Write((byte)0);

             // 4-5 color planes
             iconWriter.Write((short)0);

             // 6-7 bits per pixel
             iconWriter.Write((short)32);

             // 8-11 size of image data
             iconWriter.Write((int)memoryStream.Length);

             // 12-15 offset of image data
             iconWriter.Write((int)(6 + 16));

             // write image data
             // png data must contain the whole png data file
             iconWriter.Write(memoryStream.ToArray());
             //保存流,并将流指针定位至头部以Icon对象进行读取输出为文件
             iconWriter.Flush();

             return true;
         }

     }
     return false;

 }

 或者

/// <summary>
/// PNG转ICO
/// </summary>
/// <param name="memoryStream">源图片流</param>
/// <param name="outPath">转出图片流</param>
/// <returns></returns>
private static bool ConvertImageStreamIco(MemoryStream memoryStream, string outPath)
{
    using (FileStream output = new FileStream(outPath, FileMode.OpenOrCreate))
    {
        BinaryWriter iconWriter = new BinaryWriter(output);
        if (output != null && iconWriter != null)
        {
            // png data must contain the whole png data file
            iconWriter.Write(memoryStream.ToArray());
            //保存流,并将流指针定位至头部以Icon对象进行读取输出为文件
            iconWriter.Flush();

            return true;
        }
    }
    return false;
}

第一种方式是在网上找的参考答案,目前不知iconWriter.Write()的其他值的作用

posted @ 2024-05-14 16:43  流年sugar  阅读(69)  评论(0编辑  收藏  举报