BITMAP位图
在进行BITMAP图片进行处理的时候,首先要先对BITMAP的数据结构进行分析。
BITMAP位图的结构分为四个部分
文件头 BITMAPFILEHEADER
1 | typedef struct tagBITMAPFILEHEADER{ |
信息头 BITMAPINFOHEADER
1 | typedef struct tagBITMAPINFOHEADER{ |
在这当中,若biClrUsed为0,则说明用到的颜色为2的biBitCount次方(也就无需用到调色板了)
在这当中,biSizeImage为实际的字节数,其中,要求
也就是说,在位图当中的宽的字节数一定要是4的倍数,不是4的倍数将要对其中的字节进行补齐
举个例子,假如当前的图片是一个24位的宽度为13的图片,那么此时一行的存储模型应该是
也就是在末尾补了一个字节,从而达到了一行40字节(4的倍数)的目的。
调色板 RGBQUAD(内容可为空)
1 | typedef struct tagRGBQUAD{ |
调色板是BITMAP当中的可选项,只有需要的时候才会出现,而在有调色板的场合中,一共有biBitCount项 (RGBQUAD[biBitCount])
实际位图信息
在这里存放的是实际的位图的数据,其中数据量在BITMAPINFOHEADER有记录,在这里记录的一般是颜色的信息(比如RGB信息)又或者是有调色板的时候,记录调色板的索引值。
当然值得一提的是,这里的行的字节数一定是要4的倍数的
24位图像对R,G,B三个分量进行分离,产生3幅新的图像
在基本了解了BITMAP的内存结构之后,就可以根据其中的信息去读取图片,并分理出其中的RGB分量了。值得注意的在于,若图片的宽度不是4的倍数的时候,读取的时候要跳过行末尾的无意义的字节,否则读取出来的rgb值是错误的,而写入成新的图片的时候,同样的,要手动对行末尾进行补齐
具体实现
1 | //用于存储RGB |
对24彩色图像灰度化
灰度图实际上是一个利用心理学灰度公式来得出的一个适合人眼的灰度图片的图
在这个图片当中,由于RGB三个分量的值都是一样的(灰色的特性)因此,可以将这个图片从24位图变成一个8位的图
当我们将一个图片从24位转化为8位的时候,有几点是值得注意的
改变BITMAPFILEHEADER与BITMAPINFOHEADER
这是当然的,首先要改的就是BITMAPINFOHEADER当中的biBitCount了,毕竟这是标志了这是几位图的信息,其次,还要添加biClrUsed的信息,因为,当图片是8位图的时候,自然而然的就要用到了调色板了。
既然添加了调色板,那么就需要改变BITMAPFILEHEADER当中的biOffBits了,毕竟当中添加了一个调色板,那么图片数据的位置自然会产生变化了
最后,还要分别对BITMAPFILEHEADER当中的bfSize与BITMAPINFOHEADER当中的biSizeImage进行修改,从而使得这些数据指向的内容是符合这张图片的
添加调色板
8位图用到的颜色只有256位,因此,添加256个调色板就足够了
1 | RGBQUAD rgbQuad[256]; |
具体实现
1 | void bitmap2Gray() |
对8位灰度图进行反色
对图片进行反色是十分简单的一件事了,公式也十分的简单
具体实现和之前的是基本一致的。
当然,由于有灰度图(8位图)有调色板的存在,因此,需要在读取之前跳过调色板的内存块
1 | fseek(pfin, fileHeader.bfOffBits, 0); |
具体实现
1 | void gray2Anticolor() |