[VC] BMP文件格式

BMP文件格式由位图文件头、位图信息和像素数据三个部分组成。位图信息又由位图信息头和调色板数据组成。
在BMP格式中,位图文件头、位图信息头为固定长度,分别为14、40字节。调色板数据的多少与所用的色彩数有关,它的字节数是色彩数的四倍,每个调色板单元的前三个字节分别表示彩色的蓝、绿、红分量(注意不是常见的RGB,而是BGR),第四个字节备用。像素数据在文件的最后。
在Windows中,读入内在的是去掉了14字节位图头文件后的BMP文件,即设备无关位图(DIB)。
 
位图文件头结构
 数据类型  标识符  内容
 char  bfType[2]  ASCII字符'BM'
 DWORD  bfSize  文件大小(以4字节为单位)
 WORD  bfReserve1  备用单元1
 WORD  bfReserve2  备用单元2
 DWORD  bfOffBits  图像开始处的字节偏移
 
位图信息头结构
 数据类型  标识符  内容
 DWORD  biSize  信息头大小,40字节
 DWORD  biWidth  图像宽度,以像素为单位
 DWORD  biHeight  图像高度,以像素为单位
 WORD  biPlanes  位平面数,总为1
 WORD  biBitCount  每像素位数,为1、4、8或24
 DWORD  biCompression  压缩类型,0为不压缩
 DWORD  biSizeImage  压缩图像大小的字节数
 DWORD  biXpelspermeter  水平分辨率
 DWORD  biYpelspermeter  垂直分辨率
 DWORD  biClrUsed  使用的色彩数
 DWORD  biClrImportant  重要色彩数
 
调色板数据
在位图文件头与位图信息头之后的是调色板数据。调色板数据是从第54字节开始存放,它的数量由图像的类型决定。
 
像素数据
像素数据跟在调色板数据之后,存储位置可以由位图文件头得到,要注意以下几点:
1、BMP格式每行字节数应为4的倍数
可以由下面公式计算每行的字节数:((bits)+31)/32*4,这里的bits是每一行占的位数(很巧妙吧,这个算法) //也就是向上取整的算法,就相当于31/32得一个非常接近1的数,这样如果有余数就相当于加1.
2、像素数据是自下而上存放的,也就是从图像的最后一行开始存入文件的,从左到右的。
3、16位彩色图像采用单一位平面。
4、像素数据存放顺序为蓝、绿、红。
 
文件的读取与显示
在Windows系统中,存入内存的图像数据采用的是BMP格式,也即在Windows应用程序中,将图片读入内存,实际上就是将图片数据转换成BMP格式的位图。
下面是读取和显示BMP图片的代码:(不是自己写的)
int wid,hei,bits;
HBITMAP hBitmap = NULL;
LPSTR lpBits;
 
// 读取
void LoadBMP(LPSTR lpstrFilename)
{
   BITMAPFILEHEADER Bfh;
   LPBITMAPINFO lpBmi;
   FILE *fp;
   int BmiSize,PixSize;
 
   fp = fopen(lpstrFileName,"rb");
   fread = (&Bfh,sizeof(BITMAPFILEHEADER),1,fp);   // 读位图文件头
   BmiSize = Bfh.bfOffBits-sizeof(BITMAPFILEHEADER);   // 计算位图信息大小
   lpBmi = (LPBITMAPINFO) malloc(BmiSize);   // 申请位图信息存储空间
   fread(lpBmi,Bmisize,1,fp);   // 读入位图信息
 
   hBitmap = CreateDIBSection(NULL,lpBmi,DIB_RGB_COLORS,(VOID**)&lpBits,NULL,0);   // 建立DIBSection
   wid = lpBmi->bmiHeader.biWidth;   // 保存图像参数
   hei = lpBmi->bmiHeader.biHeight;
   bits = lpBmi->bmiHeader.biBitCount;
   PixSize = (wid*bits+31)/32*4*hei;   // 计算像素数据大小
   free(lpBmi);   // 释放位图信息
 
   fseek(fp,Bfh.bfOffBits,SEEK_SET);
   fread(lpBits,PixSize,1,fp);   // 读取像素数据
   fclose(fp);
}
 
// 显示
void DisplayDIBSection(HWND hWnd, HBITMAP hBitmap, int wid, int hei)
{
   HDC hDC,hMemDC;
   hMemDC = CreateCompatibleDC(NULL);   // 建立内存设备描述表
   SelectObject(hMemDC,hBitmap);     // 内存设备描述表选中位图
   hDC = GetDC(hWnd);   // 申请窗口句柄
   BitBlt(hDC,0,0,wid,hei,hMemDC,0,0,SRCCOPY);   // 像素数据块操作
   DeleteObject(hMemDC); 
   DeleteDC(hMemDC);   // 释放内存设备描述表
   ReleaseDC(hWnd,hDC);   // 释放窗口句柄
}
 
上面的这个显示程序体现了双缓冲显示的技术。先在内存设备描述表中画好图,再利用图像块操作函数BitBlt将图像从内存设备描述表中拷贝到“显示器”上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值