C# 下*.ICO 图标操作类

31 篇文章 1 订阅
13 篇文章 0 订阅

。NET 本身提供的ICON的操作实在太郁闷了。自己写了个ICON的类。ICON其实是255*255以下的BMP图形的集合。 只是很少地方与BMP不同。

 

  1.     /// <summary>
  2.     /// ICON 控制类 
  3.     /// zgke@Sina.com
  4.     /// </summary>
  5.     public class IconDir
  6.     {
  7.         /*
  8.             if (openFileDialog1.ShowDialog() == DialogResult.OK)
  9.             {
  10.                 IconDir T = new IconDir(openFileDialog1.FileName);
  11.                 T.GetImage(0); //获取一个ICO图形
  12.                 int Temp =T.ImageCount; //ICO数量
  13.                 T.DelImage(0);   //删除
  14.                 T.SaveData(@"C:/1.ico"); //保存成文件 
  15.             }
  16.             //添加一个ICO AddImage参数Rectangle 宽高不能超过255
  17.             IconDir MyIcon = new IconDir(); 
  18.             Image TempImage =Image.FromFile(@"c:/bfx/T5.BMP");          
  19.             MyIcon.AddImage(TempImage,new Rectangle(0,0,32,32));
  20.             MyIcon.SaveData(@"C:/1.ico");
  21.          
  22.          */
  23.         private ushort _IdReserved = 0;
  24.         private ushort _IdType = 1;
  25.         private ushort _IdCount = 1;
  26.         private IList<IconDirentry> _Identries = new List<IconDirentry>();
  27.         public IconDir()
  28.         {
  29.         }
  30.         public IconDir(string IconFile)
  31.         {
  32.             System.IO.FileStream _FileStream = new System.IO.FileStream(IconFile,System.IO.FileMode.Open);
  33.             byte[] IconData = new byte[_FileStream.Length];
  34.             _FileStream.Read(IconData, 0, IconData.Length);
  35.             _FileStream.Close();
  36.             LoadData(IconData);
  37.         }
  38.         /// <summary>
  39.         /// 读取ICO
  40.         /// </summary>
  41.         /// <param name="IconData"></param>
  42.         private void LoadData(byte[] IconData)
  43.         {
  44.             _IdReserved = BitConverter.ToUInt16(IconData, 0);
  45.             _IdType = BitConverter.ToUInt16(IconData, 2);
  46.             _IdCount = BitConverter.ToUInt16(IconData, 4);
  47.             if (_IdType != 1 || _IdReserved != 0) return;
  48.             int ReadIndex=6;
  49.             for (ushort i = 0; i != _IdCount; i++)
  50.             {
  51.                 _Identries.Add(new IconDirentry(IconData, ref ReadIndex));
  52.             }
  53.            
  54.         }
  55.         /// <summary>
  56.         /// 保存ICO
  57.         /// </summary>
  58.         /// <param name="FileName"></param>
  59.         public void SaveData(string FileName)
  60.         {
  61.             if (ImageCount == 0) return;
  62.             System.IO.FileStream _FileStream = new System.IO.FileStream(FileName, System.IO.FileMode.Create);
  63.             byte[] Temp = BitConverter.GetBytes(_IdReserved);
  64.             _FileStream.Write(Temp, 0, Temp.Length);
  65.             Temp = BitConverter.GetBytes(_IdType);
  66.             _FileStream.Write(Temp, 0, Temp.Length);
  67.             Temp = BitConverter.GetBytes((ushort)ImageCount);
  68.             _FileStream.Write(Temp, 0, Temp.Length);
  69.             for (int i = 0; i != ImageCount; i++)
  70.             {         
  71.                 _FileStream.WriteByte(_Identries[i].Width);
  72.                 _FileStream.WriteByte(_Identries[i].Height);
  73.                 _FileStream.WriteByte(_Identries[i].ColorCount);
  74.                 _FileStream.WriteByte(_Identries[i].Breserved);
  75.                 Temp = BitConverter.GetBytes(_Identries[i].Planes);
  76.                 _FileStream.Write(Temp, 0, Temp.Length);
  77.                 Temp = BitConverter.GetBytes(_Identries[i].Bitcount);
  78.                 _FileStream.Write(Temp, 0, Temp.Length);
  79.                 Temp = BitConverter.GetBytes(_Identries[i].ImageSize);
  80.                 _FileStream.Write(Temp, 0, Temp.Length);
  81.                 Temp = BitConverter.GetBytes(_Identries[i].ImageRVA);
  82.                 _FileStream.Write(Temp, 0, Temp.Length);
  83.             }
  84.             for (int i = 0; i != ImageCount; i++)
  85.             {
  86.                 _FileStream.Write(_Identries[i].ImageData, 0, _Identries[i].ImageData.Length);            
  87.             }
  88.             _FileStream.Close();
  89.         }
  90.         /// <summary>
  91.         /// 根据索引返回图形
  92.         /// </summary>
  93.         /// <param name="Index"></param>
  94.         /// <returns></returns>
  95.         public Bitmap GetImage(int Index)
  96.         {
  97.             int ReadIndex = 0;
  98.             BitmapInfo MyBitmap = new BitmapInfo(_Identries[Index].ImageData, ref ReadIndex);
  99.             return MyBitmap.IconBmp;
  100.         }
  101.         public void AddImage(Image SetBitmap,Rectangle SetRectangle)
  102.         {
  103.             if (SetRectangle.Width > 255 || SetRectangle.Height > 255) return;
  104.             
  105.           
  106.             Bitmap IconBitmap = new Bitmap(SetRectangle.Width, SetRectangle.Height);
  107.             Graphics g = Graphics.FromImage(IconBitmap);
  108.             g.DrawImage(SetBitmap, new Rectangle(0, 0, IconBitmap.Width, IconBitmap.Height), SetRectangle, GraphicsUnit.Pixel);
  109.             g.Dispose();
  110.             System.IO.MemoryStream BmpMemory = new System.IO.MemoryStream();
  111.             IconBitmap.Save(BmpMemory, System.Drawing.Imaging.ImageFormat.Bmp);
  112.          
  113.             IconDirentry NewIconDirentry = new IconDirentry();
  114.             BmpMemory.Position = 14;        //只使用13位后的数字 40开头 
  115.             NewIconDirentry.ImageData = new byte[BmpMemory.Length - 14 + 128];
  116.             BmpMemory.Read(NewIconDirentry.ImageData, 0, NewIconDirentry.ImageData.Length);
  117.             NewIconDirentry.Width = (byte)SetRectangle.Width;
  118.             NewIconDirentry.Height = (byte)SetRectangle.Height;
  119.             //BMP图形和ICO的高不一样  ICO的高是BMP的2倍
  120.             byte[] Height = BitConverter.GetBytes((uint)NewIconDirentry.Height * 2);
  121.             NewIconDirentry.ImageData[8] = Height[0];
  122.             NewIconDirentry.ImageData[9] = Height[1];
  123.             NewIconDirentry.ImageData[10] = Height[2];
  124.             NewIconDirentry.ImageData[11] = Height[3];
  125.             
  126.             
  127.             NewIconDirentry.ImageSize = (uint)NewIconDirentry.ImageData.Length;
  128.             _Identries.Add(NewIconDirentry);
  129.             uint RvaIndex = 6 + (uint)(_Identries.Count * 16);
  130.             for (int i = 0; i != _Identries.Count; i++)
  131.             {
  132.                 _Identries[i].ImageRVA = RvaIndex;
  133.                 RvaIndex += _Identries[i].ImageSize;
  134.             }
  135.         }
  136.         public void DelImage(int Index)
  137.         {
  138.            
  139.             _Identries.RemoveAt(Index);
  140.             uint RvaIndex = 6 + (uint)(_Identries.Count * 16);
  141.             for (int i = 0; i != _Identries.Count; i++)
  142.             {
  143.                 _Identries[i].ImageRVA = RvaIndex;
  144.                 RvaIndex += _Identries[i].ImageSize;
  145.             }
  146.         }
  147.         /// <summary>
  148.         /// 返回图形数量
  149.         /// </summary>
  150.         public int ImageCount { get { return _Identries.Count; } }
  151.   
  152.         private class IconDirentry
  153.         {
  154.             public IconDirentry()
  155.             {
  156.             }
  157.             public IconDirentry(byte[] IconDate, ref int ReadIndex)
  158.             {
  159.                 bWidth = IconDate[ReadIndex];
  160.                 ReadIndex++;
  161.                 bHeight = IconDate[ReadIndex];
  162.                 ReadIndex++;
  163.                 bColorCount = IconDate[ReadIndex];
  164.                 ReadIndex++;
  165.                 breserved = IconDate[ReadIndex];
  166.                 ReadIndex++;
  167.                 wplanes = BitConverter.ToUInt16(IconDate, ReadIndex);
  168.                 ReadIndex += 2;
  169.                 wbitcount = BitConverter.ToUInt16(IconDate, ReadIndex);
  170.                 ReadIndex += 2;
  171.                 dwbytesinres = BitConverter.ToUInt32(IconDate, ReadIndex);
  172.                 ReadIndex += 4;
  173.                 dwimageoffset = BitConverter.ToUInt32(IconDate, ReadIndex);
  174.                 ReadIndex += 4;
  175.                 System.IO.MemoryStream MemoryData = new System.IO.MemoryStream(IconDate, (int)dwimageoffset, (int)dwbytesinres);
  176.                 _ImageData = new byte[dwbytesinres];
  177.                 MemoryData.Read(_ImageData, 0, _ImageData.Length);
  178.             }
  179.             private byte bWidth = 16;
  180.             private byte bHeight = 16;
  181.             private byte bColorCount = 0;       
  182.             private byte breserved = 0;        //4 
  183.             private ushort wplanes = 1;         
  184.             private ushort wbitcount = 32;      //8
  185.             private uint dwbytesinres = 0;
  186.             private uint dwimageoffset = 0;         //16
  187.             private byte[] _ImageData;
  188.           
  189.             /// <summary>
  190.             /// 图像宽度,以象素为单位。一个字节
  191.             /// </summary>
  192.             public byte Width { get { return bWidth; } set { bWidth = value; } }
  193.             /// <summary>
  194.             /// 图像高度,以象素为单位。一个字节  
  195.             /// </summary>
  196.             public byte Height { get { return bHeight; } set { bHeight = value; } }
  197.             /// <summary>
  198.             /// 图像中的颜色数(如果是>=8bpp的位图则为0)
  199.             /// </summary>
  200.             public byte ColorCount { get { return bColorCount; } set { bColorCount = value; } }
  201.             /// <summary>
  202.             /// 保留字必须是0
  203.             /// </summary>
  204.             public byte Breserved { get { return breserved; } set { breserved = value; } }
  205.             /// <summary>
  206.             /// 为目标设备说明位面数,其值将总是被设为1
  207.             /// </summary>
  208.             public ushort Planes { get { return wplanes; } set { wplanes = value; } }
  209.             /// <summary>
  210.             /// 每象素所占位数。
  211.             /// </summary>
  212.             public ushort Bitcount { get { return wbitcount; } set { wbitcount = value; } }           
  213.             /// <summary>
  214.             /// 字节大小。
  215.             /// </summary>
  216.             public uint ImageSize { get { return dwbytesinres; } set { dwbytesinres = value; } }
  217.             /// <summary>
  218.             /// 起点偏移位置。
  219.             /// </summary>
  220.             public uint ImageRVA { get { return dwimageoffset; } set { dwimageoffset = value; } }
  221.             /// <summary>
  222.             /// 图形数据
  223.             /// </summary>
  224.             public byte[] ImageData { get { return _ImageData; } set { _ImageData = value; } }
  225.        
  226.         }
  227.         private class BitmapInfo
  228.         {
  229.             private uint biSize = 40;                  
  230.             private uint biWidth; 
  231.             private uint biHeight;               
  232.             private ushort biPlanes = 1;                
  233.             private ushort biBitCount;                
  234.             private uint biCompression = 0;       
  235.             private uint biSizeImage;          
  236.             private uint biXPelsPerMeter;    
  237.             private uint biYPelsPerMeter;   
  238.             private uint biClrUsed;         
  239.             private uint biClrImportant;
  240.             public IList<Color> ColorTable = new List<Color>();
  241.    
  242.             /// <summary>
  243.             /// 占4位,位图信息头(Bitmap Info Header)的长度,一般为$28  
  244.             /// </summary>
  245.             public uint InfoSize { get { return biSize; } set { biSize = value; } }
  246.             /// <summary>
  247.             /// 占4位,位图的宽度,以象素为单位
  248.             /// </summary>
  249.             public uint Width { get { return biWidth; } set { biWidth = value; } }
  250.             /// <summary>
  251.             /// 占4位,位图的高度,以象素为单位  
  252.             /// </summary>
  253.             public uint Height { get { return biHeight; } set { biHeight = value; } }
  254.             /// <summary>
  255.             /// 占2位,位图的位面数(注:该值将总是1)  
  256.             /// </summary>
  257.             public ushort Planes { get { return biPlanes; } set { biPlanes = value; } }
  258.             /// <summary>
  259.             /// 占2位,每个象素的位数,设为32(32Bit位图)  
  260.             /// </summary>
  261.             public ushort BitCount { get { return biBitCount; } set { biBitCount = value; } }
  262.             /// <summary>
  263.             /// 占4位,压缩说明,设为0(不压缩)   
  264.             /// </summary>
  265.             public uint Compression { get { return biCompression; } set { biCompression = value; } }
  266.             /// <summary>
  267.             /// 占4位,用字节数表示的位图数据的大小。该数必须是4的倍数  
  268.             /// </summary>
  269.             public uint SizeImage { get { return biSizeImage; } set { biSizeImage = value; } }         
  270.             /// <summary>
  271.             ///  占4位,用象素/米表示的水平分辨率 
  272.             /// </summary>
  273.             public uint XPelsPerMeter { get { return biXPelsPerMeter; } set { biXPelsPerMeter = value; } }   
  274.             /// <summary>
  275.             /// 占4位,用象素/米表示的垂直分辨率  
  276.             /// </summary>
  277.             public uint YPelsPerMeter { get { return biYPelsPerMeter; } set { biYPelsPerMeter = value; } }    
  278.             /// <summary>
  279.             /// 占4位,位图使用的颜色数  
  280.             /// </summary>
  281.             public uint ClrUsed { get { return biClrUsed; } set { biClrUsed = value; } }    
  282.             /// <summary>
  283.             /// 占4位,指定重要的颜色数(到此处刚好40个字节,$28)  
  284.             /// </summary>
  285.             public uint ClrImportant { get { return biClrImportant; } set { biClrImportant = value; } }
  286.             private Bitmap _IconBitMap;
  287.             /// <summary>
  288.             /// 图形
  289.             /// </summary>
  290.             public Bitmap IconBmp { get { return _IconBitMap; } set { _IconBitMap = value; } }
  291.             public BitmapInfo(byte[] ImageData, ref int ReadIndex)
  292.             {
  293.                 #region 基本数据
  294.                 biSize = BitConverter.ToUInt32(ImageData, ReadIndex);
  295.                 if (biSize != 40) return;
  296.                 ReadIndex += 4;
  297.                 biWidth = BitConverter.ToUInt32(ImageData, ReadIndex);
  298.                 ReadIndex += 4;
  299.                 biHeight = BitConverter.ToUInt32(ImageData, ReadIndex);
  300.                 ReadIndex += 4;
  301.                 biPlanes = BitConverter.ToUInt16(ImageData, ReadIndex);
  302.                 ReadIndex += 2;
  303.                 biBitCount = BitConverter.ToUInt16(ImageData, ReadIndex);
  304.                 ReadIndex += 2;
  305.                 biCompression = BitConverter.ToUInt32(ImageData, ReadIndex);
  306.                 ReadIndex += 4;
  307.                 biSizeImage = BitConverter.ToUInt32(ImageData, ReadIndex);
  308.                 ReadIndex += 4;
  309.                 biXPelsPerMeter = BitConverter.ToUInt32(ImageData, ReadIndex);
  310.                 ReadIndex += 4;
  311.                 biYPelsPerMeter = BitConverter.ToUInt32(ImageData, ReadIndex);
  312.                 ReadIndex += 4;
  313.                 biClrUsed = BitConverter.ToUInt32(ImageData, ReadIndex);
  314.                 ReadIndex += 4;
  315.                 biClrImportant = BitConverter.ToUInt32(ImageData, ReadIndex);
  316.                 ReadIndex += 4;
  317.                 #endregion
  318.                 int ColorCount = RgbCount();
  319.                 if (ColorCount == -1) return;
  320.                 for (int i = 0; i != ColorCount; i++)
  321.                 {
  322.                     byte Blue = ImageData[ReadIndex];
  323.                     byte Green = ImageData[ReadIndex + 1];
  324.                     byte Red = ImageData[ReadIndex + 2];
  325.                     byte Reserved = ImageData[ReadIndex + 3];
  326.                     ColorTable.Add(Color.FromArgb((int)Reserved, (int)Red, (int)Green, (int)Blue));
  327.                     ReadIndex+=4;                    
  328.                 }
  329.                 int Size = (int)(biBitCount * biWidth) / 8;       // 象素的大小*象素数 /字节数              
  330.                 if ((double)Size < biBitCount * biWidth / 8) Size++;       //如果是 宽19*4(16色)/8 =9.5 就+1;
  331.                 if (Size < 4) Size = 4;
  332.                 byte[] WidthByte = new byte[Size];
  333.                 _IconBitMap = new Bitmap((int)biWidth, (int)(biHeight / 2));
  334.                 for (int i = (int)(biHeight / 2); i != 0; i--)
  335.                 {
  336.                     for(int z=0;z!=Size;z++)
  337.                     {
  338.                         WidthByte[z] = ImageData[ReadIndex + z];                        
  339.                     }
  340.                     ReadIndex+=Size;
  341.                     IconSet(_IconBitMap, i - 1, WidthByte);                  
  342.                 }
  343.                
  344.                 //取掩码
  345.                 int MaskSize = (int)(biWidth / 8);
  346.                 if ((double)MaskSize < biWidth / 8) MaskSize++;       //如果是 宽19*4(16色)/8 =9.5 就+1;
  347.                 if (MaskSize < 4) MaskSize = 4;
  348.                 byte[] MashByte = new byte[MaskSize];
  349.                 for (int i = (int)(biHeight / 2); i != 0; i--)
  350.                 {
  351.                     for (int z = 0; z != MaskSize; z++)
  352.                     {
  353.                         MashByte[z] = ImageData[ReadIndex + z];
  354.                     }
  355.                     ReadIndex += MaskSize;
  356.                     IconMask(_IconBitMap, i - 1, MashByte);
  357.                 }                
  358.              
  359.             }
  360.             private int RgbCount()
  361.             {
  362.                 switch (biBitCount)
  363.                 {
  364.                     case 1:
  365.                         return 2;
  366.                     case 4:
  367.                         return 16;
  368.                     case 8:
  369.                         return 256;
  370.                     case 24:
  371.                         return 0;
  372.                     case 32:
  373.                         return 0;
  374.                     default:
  375.                         return -1;
  376.                 }
  377.             }
  378.             private void IconSet(Bitmap IconImage,int RowIndex,byte[] ImageByte)
  379.             {
  380.                 int Index = 0;
  381.                 switch (biBitCount)
  382.                 {
  383.                     case 1:
  384.                         #region 一次读8位 绘制8个点
  385.                         for (int i = 0; i != ImageByte.Length; i++)
  386.                         {
  387.                             System.Collections.BitArray MyArray =new System.Collections.BitArray(new byte[]{ImageByte[i]});
  388.                           
  389.                             if (Index >=IconImage.Width) return;
  390.                             IconImage.SetPixel( Index,RowIndex, ColorTable[GetBitNumb(MyArray[7])]);
  391.                             Index++;
  392.                             if (Index >= IconImage.Width) return;
  393.                             IconImage.SetPixel( Index,RowIndex, ColorTable[GetBitNumb(MyArray[6])]);
  394.                             Index++;
  395.                             if (Index >= IconImage.Width) return;
  396.                             IconImage.SetPixel(Index, RowIndex, ColorTable[GetBitNumb(MyArray[5])]);
  397.                             Index++;
  398.                             if (Index >= IconImage.Width) return;
  399.                             IconImage.SetPixel(Index, RowIndex, ColorTable[GetBitNumb(MyArray[4])]);
  400.                             Index++;
  401.                             if (Index >= IconImage.Width) return;
  402.                             IconImage.SetPixel(Index, RowIndex, ColorTable[GetBitNumb(MyArray[3])]);
  403.                             Index++;
  404.                             if (Index >= IconImage.Width) return;
  405.                             IconImage.SetPixel(Index, RowIndex, ColorTable[GetBitNumb(MyArray[2])]);
  406.                             Index++;
  407.                             if (Index >= IconImage.Width) return;
  408.                             IconImage.SetPixel( Index,RowIndex, ColorTable[GetBitNumb(MyArray[1])]);
  409.                             Index++;
  410.                             if (Index >= IconImage.Width) return;
  411.                             IconImage.SetPixel(Index, RowIndex, ColorTable[GetBitNumb(MyArray[0])]);
  412.                             Index++;
  413.                         }
  414.                         #endregion
  415.                         break;
  416.                     case 4:
  417.                         #region 一次读8位 绘制2个点
  418.                         for (int i = 0; i != ImageByte.Length; i++)
  419.                         { 
  420.                             int High=ImageByte[i]>>4;  //取高4位
  421.                             int Low=ImageByte[i]-(High<<4); //取低4位
  422.                             if (Index >= IconImage.Width) return;
  423.                             IconImage.SetPixel(Index, RowIndex, ColorTable[High]);
  424.                             Index++;
  425.                             if (Index >= IconImage.Width) return;
  426.                             IconImage.SetPixel(Index, RowIndex, ColorTable[Low]);
  427.                             Index++;
  428.                         }
  429.                         #endregion
  430.                         break;
  431.                     case 8:
  432.                         #region 一次读8位 绘制一个点
  433.                         for (int i = 0; i != ImageByte.Length; i++)
  434.                         {                          
  435.                             if (Index >= IconImage.Width) return;
  436.                             IconImage.SetPixel(Index, RowIndex, ColorTable[ImageByte[i]]);
  437.                             Index++;                       
  438.                         }
  439.                         #endregion
  440.                         break;
  441.                     case 24:
  442.                         #region 一次读24位 绘制一个点
  443.                         
  444.                         for (int i = 0; i != ImageByte.Length / 3; i++)
  445.                         {
  446.                             if (i >= IconImage.Width) return;
  447.                             IconImage.SetPixel(i, RowIndex, Color.FromArgb(ImageByte[Index + 2], ImageByte[Index + 1], ImageByte[Index]));
  448.                             Index += 3;
  449.                         }
  450.                         #endregion
  451.                         break;
  452.                     case 32:
  453.                         #region 一次读32位 绘制一个点
  454.                       
  455.                         for (int i = 0; i != ImageByte.Length/4; i++)
  456.                         {
  457.                             if (i >= IconImage.Width) return;
  458.                        
  459.                             IconImage.SetPixel(i, RowIndex, Color.FromArgb(ImageByte[Index + 2], ImageByte[Index + 1], ImageByte[Index]));
  460.                             Index+=4;
  461.                         }
  462.                         #endregion
  463.                         break;
  464.                     default:
  465.                         break;
  466.                 }                
  467.             }
  468.             private void IconMask(Bitmap IconImage, int RowIndex, byte[] MaskByte)
  469.             {
  470.               
  471.                 System.Collections.BitArray Set = new System.Collections.BitArray(MaskByte);
  472.                 int ReadIndex=0;
  473.                 for (int i = Set.Count; i !=0 ; i--)
  474.                 {
  475.                     if (ReadIndex >= IconImage.Width) return;
  476.                     Color SetColor = IconImage.GetPixel(ReadIndex, RowIndex);
  477.                     if (!Set[i-1])IconImage.SetPixel(ReadIndex, RowIndex, Color.FromArgb(255, SetColor.R, SetColor.G, SetColor.B));
  478.                     ReadIndex++;
  479.                                 
  480.                 }
  481.                
  482.             }
  483.             private int GetBitNumb(bool BitArray)
  484.             {
  485.                 if (BitArray) return 1;
  486.                 return 0;                
  487.             }
  488.          
  489.         }
  490.     }
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值