一、BMP位图的文件格式
BMP文件的数据按照从文件头开始的先后顺序分为四个部分:
◆ 位图文件头(bmp file header): 提供文件的格式、大小等信息
◆ 位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息
◆ 调色板(color palette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表
◆ 位图数据(bitmap data):图像数据区
值得注意的是: BMP位图的调色板结构存在于单色、16色、256色位图结构中,256色以上(8位)以上的位图一般没有调色板结构
BMP图片文件格式表如下
数据名称 | 所占存储大小 |
位图文件头 | 14字节 |
位图信息头 | 40字节 |
调色板 | 4*(颜色数) |
位图数据 | 由具体图像决定 |
关于调色板结构
bmiCOLOR[]即调色板结构,由若干表项组成,每一个表项是一个 RGBQUAD类型的结构,一种颜色就由一个表项所决定,即调色板所占存储与颜色数有关
RGBQUAD类型的组成如下,总共占用4个字节,每一项各占一个字节
typedef tagRGBQUAD{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReseved;
}RGBQUAD
二、MFC下位图的保存
void CBMP_DemoView::OnFileSaveAs()
{// TODO: Add your command handler code hereCBMP_DemoDoc* pDoc = GetDocument();//获取文档指针ASSERT_VALID(pDoc);if(pDoc->m_pDib == NULL){AfxMessageBox("Error!");return;}BITMAPFILEHEADER bmpf;//文件头BITMAPINFOHEADER bmpi;//信息头RGBQUAD rgb[256];//调色板数组int Widthbytes;CFile bmpFile;//文件CString strFileName;//文件名称
// m_nCols = pbmi->bmiHeader.biWidth;
// m_nRows = (long)(pbmi->bmiHeader.biHeight);
//row 行 height
//cols 列 widthint mcols = pDoc->m_pDib->m_nCols;int mrows = pDoc->m_pDib->m_nRows;PBITMAPINFO pbmpi=pDoc->m_pDib->pbmi;//引用调色板数据int bit_count=pDoc->m_pDib->m_nBitCounts;unsigned char* m_pData=NULL;m_pData = pDoc->m_pDib->pImgData;//文件名CFileDialog dlg(FALSE,"*.BMP",NULL,NULL,"位图文件(*.BMP)|*.bmp;*.BMP|");if(!dlg.DoModal()==IDC_SAVE)return;strFileName=dlg.GetPathName();if(bmpFile.Open(strFileName,CFile::modeCreate|CFile::modeReadWrite)==0)return;Widthbytes=(mcols*3+3)/4*4;//位图对齐,确保为4的倍数//头文件填写bmpf.bfType=0x4d42;bmpf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);bmpf.bfSize=bmpf.bfOffBits+Widthbytes*mrows;bmpf.bfReserved1=0;bmpf.bfReserved2=0;
//信息头填写bmpi.biSize=sizeof(BITMAPINFOHEADER);bmpi.biWidth=mcols;bmpi.biHeight=mrows;bmpi.biPlanes=1;bmpi.biBitCount=8;//8位bmpi.biCompression=0;bmpi.biSizeImage=0;bmpi.biXPelsPerMeter=0;bmpi.biYPelsPerMeter=0;bmpi.biClrUsed=0;bmpi.biClrImportant=0;
//颜色表填写for(int i=0;i<256;i++)
{rgb[i].rgbRed=pbmpi->bmiColors[i].rgbRed;rgb[i].rgbGreen=pbmpi->bmiColors[i].rgbGreen;rgb[i].rgbBlue=pbmpi->bmiColors[i].rgbBlue;
}//pDoc->m_pDib->Close();
//bmpFile.SeekToBegin();
bmpFile.Write(&bmpf,sizeof(bmpf));//写文件头
bmpFile.Write(&bmpi,sizeof(bmpi));//写信息头
bmpFile.Write(&rgb[0],(sizeof(RGBQUAD)*256));//写调色板
bmpFile.Write(m_pData,(mcols * mrows * bit_count /8));//写图像数据信息
bmpFile.Close();}