手动修改Icon图标的颜色深度(张佩)

手动修改Icon图标的颜色深度

-- 张佩



这本是雕虫小技,但依旧有用,所以写在这里让需要的人看。本文要讲的是怎样手动修改Icon图标的大小和颜色深度。
        问题本身是这样的:我发现在MFC项目中新建图标,它的颜色色度永远都是4bit(即16色),而不是24bit(或0x1000000种颜色)。
解决这个问题最好的办法是使用ICON软件,创建或修改ICON图标。但因为手头没有,并由于研究的兴趣,我选择尝试手动修改Icon文件。在实际操作的过程中,微软文档《Icons in Win32》对我极有帮助。另一篇差不多是它的中文翻译,是《Windows图标-Icon文件格式分析》,也不错。

1. ICON头

和BMP文件相比,ICON文件要再多了一个头。也就是说,如果把一个16*16或32*32这样大小的BMP文件,前置一个Icon头就能变成一个Icon文件了。
        下面是Icon头的结构定义:
typedef struct
{
  WORD idReserved; // Reserved (must be 0)
  WORD idType; // Resource Type (1 for icons)
  WORD idCount; // How many images?
  ICONDIRENTRY idEntries[1]; // An entry for each image (idCount)
} ICONDIR, *LPICONDIR;
         前面是3个word型变量。第一个是保留位(注释指明,一定是0),第二个为类型变量,Icon因设为1,第三个变量是图片数量,一张Icon中可以包含多个BMP图片,对应下面的多个ICONDIRENTRY结构。每个ICONDIRENTRY结构表示一张BMP图,其结构大小是16Byte。所以ICON头的总大小为:6+16×idCount。
下面是ICONDIRENTRY结构定义:
typedef struct
{
  BYTE bWidth; // Width, in pixels, of the image
  BYTE bHeight; // Height, in pixels, of the image
  BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
  BYTE bReserved; // Reserved ( must be 0)
  WORD wPlanes; // Color Planes
  WORD wBitCount; // Bits per pixel
  DWORD dwBytesInRes; // How many bytes in this resource?
  DWORD dwImageOffset; // Where in the file is this image?
} ICONDIRENTRY, *LPICONDIRENTRY;

        前两个变量指出了图像的大小,由于Icon图片都是长宽相等的,所以一般有16*16,32*32,48*48这几种。

        最后一个DWORD变量dwImageOffset,指明对应的BMP文件在整个文件中的偏移。可以用二进制编辑软件打开一个ICON文件后,进行操练。假设某个dwImageOffset值为0X000044E6,移动鼠标到此偏移处,由此开始的一段数据块,就是一个标准的BMP文件了。我们下面就是要通过这种方法,定位BMP文件后,改变BMP文件的颜色等相关属性。

        首先确定图像的Index,即它在ICONDIRENTRY列表中的位置,然后找到其BMP文件在ICON文件中的偏移,并定位到此偏移处等待进一步处理。最简单的情况是Icon文件中只有一个Bmp图像,那么Bmp文件的偏移一定总是22。

       2. BMP头

现在还需再分析BMP文件。BMP文件由头和体两个部分组成,我们只要分析其头结构即可,下面是结构体BITMAPINFOHEADER的定义:
typedef struct tagBITMAPINFOHEADER { /* bmih */
  DWORD biSize;
  LONG biWidth;
  LONG biHeight;
  WORD biPlanes;
  WORD biBitCount;
  DWORD biCompression;
  DWORD biSizeImage;
  LONG biXPelsPerMeter;
  LONG biYPelsPerMeter;
  DWORD biClrUsed;
  DWORD biClrImportant;
} BITMAPINFOHEADER;

表示颜色深度的变量biBitCount位于结构体中的第15个字节。它一般有几种取值,即4、8、16、24、32,分别代表了各种不同的颜色深度,见得较多的是4,即共能表示16种颜色。改成24后,能表示的颜色范围变成了16777216(0x1000000)种。
最后两个DWORD型的变量(偏移31字节)能表示的颜色数量,4色对应0x10,即16色。当我们改成24后,应该把它改成0x1000000,即能表示更多的颜色。也可以把其值改成0,0表示颜色数量无限制,相当于最大。

3. 观其效

保存图标文件后重新在VC中打开,到资源里面重新查看Icon属性,是不是已经改变了?现在可以从画板中打开一个图片,挖一块色彩丰富的图片粘帖到Icon中,它的颜色就不会失真了。
        本文介绍的这种方法,可谓九牛拉一草,大力气用在小地方。 但技术爱好者处于研究的目地,这种死功夫又往往是必需的。

你可能感兴趣的:(image,struct,mfc,byte,colors,icons)