电子相册之bitmap
位图文件主要分为3部分:1. 文件信息头 14Byte
2. 位图信息头 40Byte
3. RGB颜色阵列 由图像长宽尺寸决定
1. 文件信息头
定义结构体:
typedef struct tagBITMAPFILEHEADER { /* bmfh */
UINT bfType;
DWORD bfSize;
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;
DWORD bfSize;
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
bfType:必须是0x4D42
bfSize: 位图文件的大小
bfReserved1:保留成员1,必须为0
bfReserved2:保留成员2,必须为0
bfOffBits:从文件头开始到实际的位图数据之间的偏移量
2. 位图信息头
定义结构体:
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;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
biSize:结构体大小,以字为单位(4字节),4字节对齐
biWidth: 图像宽度,以像素为单位
biHeight:图像高度,以像素为单位。大于0,图像是倒向的;小于0,图像是正向的。大多数为倒向的。就是说图像数据是从图像的左下脚的像素开始一行一行的存储的。
biPlanes:总是为1
biBitCount:每像素所占的比特数(位数),一般为24或32位
biCompression:图像数据压缩类型,讨论没有压缩的类型:BI_RGB
biSizeImage:说明图像的大小,以字节为单位。为BI_RGB类型时可以设置为0
biXPelsPerMeter:水平分辨率,以像素/米表示
biYPelsPerMeter:垂直分辨率,以像素/米表示
biClrUsed:说明位图实际使用的调色板中的索引数,为0就是使用所有的索引数
biClrImportant:说明对图像显示有重要影响的索引数,为0就是都重要
3. RGB颜色阵列
windows下RGB颜色阵列实际上是以BGR格式来存储的,24位就是从高位到低位每个字节存储的颜色数据依次是BGR,32位的RGB位图从高位到低位依次是BGR以及最低一个字节位图像透明度
4. 加载文件头
//Load the file header
BITMAPFILEHEADER header;
memset(&header, 0, sizeof(header));
inf.read((char*)&header, sizeof(header));
if(header.bfType != 0x4D42)
return false;
5. 加载位图信息
//Load the image information header
BITMAPINFOHEADER infoheader;
memset(&infoheader, 0, sizeof(infoheader));
inf.read((char*)&infoheader, sizeof(infoheader));
m_iImageWidth = infoheader.biWidth;
m_iImageHeight = infoheader.biHeight;
m_iBitsPerPixel = infoheader.biBitCount;
6. 行对齐
加载得到的位图信息的每个像素是4字节对齐的,如果图像的像素不是4字节对齐,会自动在位后面补零,凑成4字节对齐。
这样图像数据的长度就是:
//Calculate the image data size
int iLineByteCnt = (((m_iImageWidth*m_iBitsPerPixel) + 31) >> 5) << 2;
m_iImageDataSize = iLineByteCnt * m_iImageHeight;