将图像转换为c#中的图标

我有一个项目将图像格式文件转换为图标文件。 但是,在转换图像后,图像的颜色会发生变化。

这是我的代码

Bitmap theBitmap = new Bitmap(theImage, new Size(width, height)); IntPtr Hicon = theBitmap.GetHicon();// Get an Hicon for myBitmap. Icon newIcon = Icon.FromHandle(Hicon);// Create a new icon from the handle. FileStream fs = new FileStream(@"c:\Icon\" + filename + ".ico", FileMode.OpenOrCreate);//Write Icon to File Stream 

在此处输入图像描述

谁知道怎么解决这个问题?

Bitmap.GetHicon() 非常擅长创建可在任何可运行.NET代码的Windows版本上运行良好的图标。 包括旧的,Windows 98和Windows 2000.尚未支持花式图标的操作系统。

所以你得到的是一个只有 16种颜色的图标,使用带有基本颜色的预制调色板。 温和地说,这往往会产生令人失望的结果。

Bitmap或Icon类没有获得更好结果的选项。 通常,您需要使用图标编辑器来创建好的图标。 其中应包含不同大小和颜色深度的多个图像,以便它们适用于任何video适配器设置和任何操作系统版本。 特别是从1600万色到256色或16色的色彩减少是一种非常重要的操作,有多种方法可以做到,它们都不是完美的。 一个好的图标编辑器有你需要的工具,使它能够很好地工作。

如果您只需要32位图标,则可以使用FreeImage http://freeimage.sourceforge.net

 string icoFile = "C:\path\to\file.ico"; FreeImageBitmap fiBitmap = new FreeImageBitmap(theBitmap); fiBitmap.Rescale(48, 48, FREE_IMAGE_FILTER.FILTER_BICUBIC); fiBitmap.Save(icoFile); fiBitmap.Rescale(32, 32, FREE_IMAGE_FILTER.FILTER_BICUBIC); fiBitmap.SaveAdd(icoFile); fiBitmap.Rescale(16, 16, FREE_IMAGE_FILTER.FILTER_BICUBIC); fiBitmap.SaveAdd(icoFile); 

如果要完全支持32,8,1和1位图标,则必须创建自己的ico格式编写器。 我在开发自己的基于C#的png到ico转换器http://iconverticons.com时遇到了这个问题

实际上并不太难; 您需要的ico文件格式规范如下: http : //msdn.microsoft.com/en-us/library/ms997538.aspx

你还需要这里的Bitmap头规范,因为ico是位图的一个子集: http : //msdn.microsoft.com/en-us/library/dd183376.aspx

你可以试试这个:

 Bitmap theBitmap = new Bitmap(theImage, new Size(width, height)); theBitmap.Save(@"C:\Icon\" + filename + ".ico", System.Drawing.Imaging.ImageFormat.Icon); 

似乎.Net Framework没有任何Icon Encoder; 所以你不能保存任何真正的图标文件。 保存的文件只是一个PNG文件。

解决了Vista及更高版本

如果你必须动态生成图标(我的应用程序有不断变化的数字),如果你不得不使用编辑器,那你就不走运了。

Ruiwei Bu(darkfall)有一个github要点,展示如何。 当然,我们当然不支持XP,而且这对我们来说也是如此。

使用类的示例我将该代码放入:

 Dim ico As New Icons With {.state = Iconstates.OK, .UpgradeNum = "123"} Dim tempfile = "C:\file5.ico" ico.GetIcon(tempfile) Dim newicon As New Icon(tempfile) 

带有darkfall代码的类:

 Imports System.Drawing.Imaging Imports System.IO Public Class Icons Property UpgradeNum As String Property state As Iconstates Function GetIcon(Optional OptionalSave As String = "") As Icon Dim bmp As New Bitmap(16, 16) Using g = Graphics.FromImage(bmp) g.Clear(Color.Transparent) g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias Select Case state Case Iconstates.OK g.FillEllipse(Brushes.Green, 1, 1, 14, 14) End Select g.DrawString(UpgradeNum, New Font("Small Fonts", 6), Brushes.Aquamarine, 0, 0) End Using bmp.Save(OptionalSave & ".png") Dim outputStream As New MemoryStream() Dim size As Integer = bmp.Size.Width If Not ConvertToIcon(bmp, outputStream, size) Then Return Nothing End If If OptionalSave > "" Then Using file = New FileStream(OptionalSave, FileMode.Create, System.IO.FileAccess.Write) outputStream.WriteTo(file) file.Close() End Using End If outputStream.Seek(0, SeekOrigin.Begin) Return New Icon(outputStream) End Function '''  ''' Converts a PNG image to an icon (ico) '''  ''' The input stream ''' The output stream ''' Needs to be a factor of 2 (16x16 px by default) ''' Preserve the aspect ratio ''' Wether or not the icon was succesfully generated Public Shared Function ConvertToIcon(inputBitmap As Bitmap, output As Stream, Optional size As Integer = 16, Optional preserveAspectRatio As Boolean = False) As Boolean Dim width As Single = size, height As Single = size Dim newBitmap = New Bitmap(inputBitmap, New Size(CInt(width), CInt(height))) If newBitmap Is Nothing Then Return False End If ' save the resized png into a memory stream for future use Using memoryStream As New MemoryStream() newBitmap.Save(memoryStream, ImageFormat.Png) Dim iconWriter = New BinaryWriter(output) If output Is Nothing OrElse iconWriter Is Nothing Then Return False End If ' 0-1 reserved, 0 iconWriter.Write(CByte(0)) iconWriter.Write(CByte(0)) ' 2-3 image type, 1 = icon, 2 = cursor iconWriter.Write(CShort(1)) ' 4-5 number of images iconWriter.Write(CShort(1)) ' image entry 1 ' 0 image width iconWriter.Write(CByte(width)) ' 1 image height iconWriter.Write(CByte(height)) ' 2 number of colors iconWriter.Write(CByte(0)) ' 3 reserved iconWriter.Write(CByte(0)) ' 4-5 color planes iconWriter.Write(CShort(0)) ' 6-7 bits per pixel iconWriter.Write(CShort(32)) ' 8-11 size of image data iconWriter.Write(CInt(memoryStream.Length)) ' 12-15 offset of image data iconWriter.Write(CInt(6 + 16)) ' write image data ' png data must contain the whole png data file iconWriter.Write(memoryStream.ToArray()) iconWriter.Flush() End Using Return True End Function End Class ' https://gist.github.com/darkfall/1656050 '======================================================= 'Service provided by Telerik (www.telerik.com) 'Conversion powered by NRefactory. 'Twitter: @telerik 'Facebook: facebook.com/telerik '=======================================================