Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在c语言中将图像转换为图标#_C#_Bitmap - Fatal编程技术网

C# 在c语言中将图像转换为图标#

C# 在c语言中将图像转换为图标#,c#,bitmap,C#,Bitmap,我有一个将图像格式文件转换为图标文件的项目。但是,在转换图像后,图像的颜色会发生变化 这是我的密码 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

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

这是我的密码

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 theBitmap = new Bitmap(theImage, new Size(width, height));

theBitmap.Save(@"C:\Icon\" + filename + ".ico", System.Drawing.Imaging.ImageFormat.Icon);
GetHicon()非常擅长创建在任何可以运行.NET代码的Windows版本上运行良好的图标。包括旧的Windows 98和Windows 2000。尚未支持奇特图标的操作系统

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

位图或图标类没有获得更好结果的选项。通常,您需要使用图标编辑器来创建好的图标。它应该包括不同大小和颜色深度的多个图像,这样它们就可以很好地与任何视频适配器设置和任何操作系统版本配合使用。特别是从1600万色减少到256色或16色是一个非常简单的操作,有多种方法可以实现,没有一种方法是完美的。一个好的图标编辑器有足够的工具使其工作良好



更新:成为一个非常过时的问题,XP已经过时了。现在,您可以使用生成一个非常好看的图标。

如果您只需要32位图标,您可以使用FreeImage

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

其实并不太难;您需要的ico文件格式规范如下:

由于ico是位图的一个子集,因此您还需要此处的位图头规范:
似乎
.Net Framework
没有任何图标编码器;所以你不能保存任何真正的图标文件。保存的文件仅为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)
具有暗球代码的类:

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




  ''' <summary>
  ''' Converts a PNG image to an icon (ico)
  ''' </summary>
  ''' <param name="inputBitmap">The input stream</param>
  ''' <param name="output">The output stream</param>
  ''' <param name="size">Needs to be a factor of 2 (16x16 px by default)</param>
  ''' <param name="preserveAspectRatio">Preserve the aspect ratio</param>
  ''' <returns>Wether or not the icon was succesfully generated</returns>
  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
'=======================================================
导入System.Drawing.Imaging
导入System.IO
公共类图标
属性UpgradeNum作为字符串
属性状态为Iconstates
函数GetIcon(可选选项Save As String=“”)作为图标
将bmp变暗为新位图(16,16)
使用g=Graphics.FromImage(bmp)
g、 透明(彩色、透明)
g、 SmoothingMode=Drawing2D.SmoothingMode.AntiAlias
选择案例状态
Case-Iconstates.OK
g、 FillEllipse(画笔:绿色、1、1、14、14)
结束选择
g、 拉丝(UpgradeNum,新字体(“小字体”,6),画笔。海蓝宝石,0,0)
终端使用
bmp.Save(可选保存和“.png”)
Dim outputStream作为新内存流()
尺寸为整数=bmp.size.Width
如果不是ConvertToIcon(bmp、outputStream、size),则
一无所获
如果结束
如果选择Save>“”则
使用file=newfilestream(可选保存、FileMode.Create、System.IO.FileAccess.Write)
outputStream.WriteTo(文件)
file.Close()文件
终端使用
如果结束
outputStream.Seek(0,SeekOrigin.Begin)
返回新图标(outputStream)
端函数
''' 
''将PNG图像转换为图标(ico)
''' 
''输入流
''输出流
''需要是2的系数(默认为16x16 px)
''保留纵横比
''图标是否成功生成
公共共享函数ConvertToIcon(输入位图为位图,输出为流,可选大小为整数=16,可选保留AspectRatio为布尔=False)为布尔值
尺寸宽度为单个=尺寸,高度为单个=尺寸
Dim NEBITMAP=新位图(输入位图,新大小(CInt(宽度),CInt(高度)))
如果newBitmap什么都不是,那么
返回错误
如果结束
'将调整大小的png保存到内存流中以备将来使用
将memoryStream用作新的memoryStream()
保存(memoryStream,ImageFormat.Png)
Dim iconWriter=新的二进制写入程序(输出)
如果输出为Nothing或LSE iconWriter为Nothing,则
返回错误
如果结束
'0-1保留,0
iconWriter.Write(CByte(0))
iconWriter.Write(CByte(0))
'2-3图像类型,1=图标,2=光标
iconWriter.Write(CShort(1))
“4-5个图像数量
iconWriter.Write(CShort(1))
'图像条目1
“0图像宽度”
iconWriter.Write(CByte(宽度))
'1图像高度
iconWriter.Write(CByte(高度))
'2颜色的数量
iconWriter.Write(CByte(0))
'3保留
iconWriter.Write(CByte(0))
'4-5色平面
iconWriter.Write(CShort(0))
'每像素6-7位
iconWriter.Write(CShort(32))
'8-11图像数据的大小
iconWriter.Write(CInt(memoryStream.Length))
'12-15图像数据的偏移量
iconWriter.Write(CInt(6+16))
'写入图像数据
'png数据必须包含整个png数据文件
iconWriter.Write(memoryStream.ToArray())
iconWriter.Flush()
终端使用
返回真值
端函数
末级
' https://gist.github.com/darkfall/1656050
'=======================================================
“Telerik提供的服务(www.Telerik.com)
'由工厂提供动力的转换。
推特:@telerik
Facebook:Facebook.com/telerik
'=======================================================

这是我的方法,可以将png转换为图标,包括透明度:

public void ConvertToIco(Image img, string file, int size)
{
    Icon icon;
    using (var msImg = new MemoryStream())
    using (var msIco = new MemoryStream())
    {
        img.Save(msImg, ImageFormat.Png);
        using (var bw = new BinaryWriter(msIco))
        {
            bw.Write((short)0);           //0-1 reserved
            bw.Write((short)1);           //2-3 image type, 1 = icon, 2 = cursor
            bw.Write((short)1);           //4-5 number of images
            bw.Write((byte)size);         //6 image width
            bw.Write((byte)size);         //7 image height
            bw.Write((byte)0);            //8 number of colors
            bw.Write((byte)0);            //9 reserved
            bw.Write((short)0);           //10-11 color planes
            bw.Write((short)32);          //12-13 bits per pixel
            bw.Write((int)msImg.Length);  //14-17 size of image data
            bw.Write(22);                 //18-21 offset of image data
            bw.Write(msImg.ToArray());    // write image data
            bw.Flush();
            bw.Seek(0, SeekOrigin.Begin);
            icon = new Icon(msIco);
        }
    }
    using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write))
    {
        icon.Save(fs);
    }
}

我创建了这个简单的函数,它获取要转换的图像字符串和保存的路径。ico可以在chrome和其他浏览器上运行

public void ConvertToIco(string pathImageToConvert, string pathToSave)
{
    Bitmap bmp = new Bitmap(pathImageToConvert);
    bmp.Save(pathToSave, System.Drawing.Imaging.ImageFormat.Icon);
}
下面是path的一个示例

pathImageToConvert = "yourpath/" + image.extension
pathToSave  = "yourpath/" + image.ico  

你必须通过一些更好的处理来运行它
GetHicon()
不是无损转换。中有几个链接
pathImageToConvert = "yourpath/" + image.extension
pathToSave  = "yourpath/" + image.ico