本人之前没写过什么代码,只是简单地做过几个Android App,都是自己写着玩,连码农都算不上,代码功底说实话不怎么地。最近公司说可以让做开发,不过是C++,MFC方面。C++我不怎么懂,MFC更是不怎么熟悉。开始做个BMP文件显示特效处理的小程序,虽然不怎么懂,也只能边学编写了。由于水平有限,代码里很多地方会不入高手法眼,不喜勿喷,新手学习经验记录笔记而已。
就当自己是什么都不懂,就把觉得应该记录的地方即下来吧。如有不对的地方,请指正。
一.计算机存储相关的概念:
1.1 Bit(位):计算机中最小的存储单位,就是二进制中的0或者1, 1 Bit就是一个0或者一个1
1.2 Byte(字节):比Bit稍大点的单位,1 Byte = 8 Bit
1.3 WORD(字):MSDN中解释为16 Bit的整数,即1 Word = 2 Byte但这个似硬件相关,数据总线为16位,则1word为2byte;32位时,1word为4byte
1.4 DWORD(双字):就是2个字的大小了,1 DWORD = 2 WORD = 4 Byte = 32 Bit
1.5 RGB:简单理解就是红绿蓝三种颜色,一般情况下用3个字节表示,即R占8 Bit,G占8 Bit,B占8 Bit,每个RGB的范围是0-255,当然这只是RGB的一种表现形式, 还有RGB555, RGB565等其他形式,先记成各占8 Bit便于理解。
二.Bitmap的相关概念
2.1 简单概念:常见的BMP文件有单色,16色,256色,24位,32位的bmp文件。为什么会有这些差异呢?因为早期系统和硬件设备表示颜色的能力有限,同时也是为了节约存储空间的成本,所以才会有了这些差异。简单理解为单色,16色,256色表示的颜色如字面意思,即有2种颜色,16种颜色,256种颜色的bmp,至于24 Bit和32 Bit的可以标示2^24和2^32种颜色。24位位图一个像素是24位,刚好是一个字节代表一个RGB分量。32位位图4个字节代表一个像素,相比24位位图,它多了一个Alpha通道,在最高位,表示图像的透明度,不过目前还没用到过这个值。
2.2 DIB和DDB:(本人的理解)DIB是和显示设备无关的Bmp文件,因为在它的文件中存储了各种颜色的表示方式。而DDB是和显示设备相关的bmp文件,系统在显示它时,会依赖于在系统中当前选中的调色板(有多少种颜色),至于系统中调色板的表示能力是多少,这个就有差异了,所以一般使用的DIB方式的存储的bmp文件。
2.3 BMP文件结构:想象一个BMP文件在内存中总共占一堆空间,按照标准,把这对内存空间又划分成几个不同的部分。把这段内存想象为自上而下的结构,那么BMP文件在内存中可以分为以下几个部分:
BITMAPFILEHEADER
typedef struct tagBITMAPFILEHEADER {
WORD bfType; //占2个字节(1个WORD),二进制读BMP文件时,头两个字节的值应该是0x424D,即字符'BM',这个值是固定的
DWORD bfSize; //占4个字节(1个DWORD),读取这四个字节的内容就是代表着BMP文件的大小,用Byte表示
WORD bfReserved1; //保留位,占1个字节,值总是0
WORD bfReserved2; //保留位,占1个字节,值总是0
DWORD bfOffBits; //4个字节,表示BITMAPINFOHEADER,RGBQUAD,Color-Index array的内存起始地址
}
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; //4个字节,二进制读取此4个字节的内容就是biSize,一般情况下这个值是40,但是有些特殊的bmp文件不是40,不知道为什么
LONG biWidth; //4个字节,图像的宽度,单位是像素,即一行有多少个像素点
LONG biHeight; //4个字节,图像的高度,单位是像素,一列有多宽
WORD biPlanes; //2个字节,这个值总是1
WORD biBitCount; //2个字节,这个值很重要,这个值可能为1,4,8,16,24,32。表示bmp文件中颜色的个数,即有2^biBitCount个颜色,也就是说有2中颜色(单色,黑白)
//16色,256色位图,16位位图,24位位图,32位位图。一般说来,单色,16色,256色位图中都会有调色板。16位位图可能会有调色板,这个值和
//biCompression,biClrUsed合起来会有不同的RGB的表示方式,这个就比较特殊了,没具体研究过
DWORD biCompression; //bmp文件的压缩方式,一般用BI_RGB(值是0)表示不压缩,如果是其他值,表示不同的压缩方式,这个也没仔细研究了
DWORD biSizeImage; //文件大小
LONG biXPelsPerMeter; //表示每米有多少像素,水平方向,没怎么用,不知道有什么用途
LONG biYPelsPerMeter; //类似上一个,不过是垂直方向
DWORD biClrUsed; //表示调色板中或者图片中使用的颜色的数目,一般是0,似乎不需要关注
DWORD biClrImportant; //表示显示这个bmp需要多少种颜色,一般是0,表示所有颜色都需要,即所有颜色都很重要,似乎也不需要特别关注
}
一般情况下,只需要关注,biSzie, biWidth, biHeight, biBitCount, biCompression这几个值
typedef struct tagRGBQUAD { BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; }这个就是调色板,一般是16位位图以下才有,在bmp文件中,调色板是一个数组,里面存储了不同颜色的RGB值,可以把它想象成画图板的调色板就就可以了。
Color-Index