1.对于BMP图像的个人理解
一张BMP图像通常包含4部分,文件头BITMAPFILEHEADER,信息头BITMAPINFOHEADER,颜色表,实际数据。
其中读取24位图像(biBitcount=24)和8位图像(biBitcount==8)的区别就是24位图像颜色表为空,而8位图像则含有256种颜色。
话不多说直接上代码。
2.基于VS2012 mfc的bmp图像读取代码
//定义变量
BITMAPFILEHEADER Fileheader;//文件头
BITMAPINFOHEADER Infoheader;//信息头
BITMAPINFO * pBmpInfo ;//(该变量我也没整明白是干嘛的显示的时候用到,不知道为啥要用这个,不用信息头)
int bmpwidth;//图像宽高
int bmpheight;//
unsigned char *pBmpbuf;//图像指针
RGBQUAD *pColorTable;//颜色表
int biBitcount;//图像类型每个像素位数
//定义函数
bool readBmp(CString bmpName);//读图函数
void DisplayBmp();//显示图像
/源代码
void CMy20190812ReadimageDlg::OnBnClickedButtonreadimage()
{
// TODO: 在此添加控件通知处理程序代码
CString strFileName;//记录选择文件路径
strFileName="E:/系统学习/opencv/相关图像/5.bmp";
bool readinage =readBmp(strFileName);
if (!readinage)
{
AfxMessageBox("读取图像失败!");
}
DisplayBmp();
}
bool CMy20190812ReadimageDlg:: readBmp(CString bmpName)
{
FILE *fp;
fp=fopen(bmpName,"rb");
if (fp==0) return 0;
//跳过头文件
// 函数功能是把文件指针指向文件的开头,需要包含头文件stdio.h
//
// fseek
//函数名: fseek
// 功 能: 重定位流上的文件指针
// 用 法: int fseek(FILE *stream, long offset, int fromwhere);
// 描 述: 函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere为基准,偏移offset个字 节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。
fseek(fp,sizeof(BITMAPFILEHEADER),0);
// fread是一个函数,它从文件流中读数据,最多读取count个项,每个项size个字节,如果调用成功返回实际读取到的项个数(小于或等于count),如果不成功或读到文件末尾返回 0。
//函数原型
//size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;
//参 数
//buffer 用于接收数据的内存地址
//size 要读的每个数据项的字节数,单位是字节
//count 要读count个数据项,每个数据项size个字节.
//stream 输入流
//返回值
//返回真实读取的项数,若大于count则意味着产生了错误。另外,产生错误后,文件位置指示器是无法确定的。若其他stream或buffer为空指针,或在unicode模式中写入的字节数为奇数,此函数设置errno为EINVAL以及返回0.
fread(&Infoheader,sizeof(BITMAPINFOHEADER),1,fp);
bmpwidth=Infoheader.biWidth;
bmpheight=Infoheader.biHeight;
biBitcount=Infoheader.biBitCount;
pBmpInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];
if (!pBmpInfo)
{
AfxMessageBox("memory error!");
return 0;
}
if (biBitcount==8)
{
pColorTable=new RGBQUAD[256];
fread(pColorTable,sizeof(RGBQUAD),256,fp);
}
memcpy(pBmpInfo,&Infoheader,sizeof(BITMAPINFOHEADER));
//计算每行所占的字节数
int lineByte=(bmpwidth*biBitcount/8+3)/4*4;
pBmpbuf=new unsigned char[lineByte * bmpheight];
fread(pBmpbuf,1,lineByte * bmpheight,fp);
fclose(fp);
return 1;
}
void CMy20190812ReadimageDlg::DisplayBmp()
{
CRect rect;//定义矩形类
CWnd *pWnd=GetDlgItem(IDC_STATIC_PIC1);//获得pictrue控件窗口的句柄
pWnd->GetClientRect(&rect);//获得pictrue控件所在的矩形区域
CDC *pDC=pWnd->GetDC();//获得pictrue控件的DC
//显示图片
pDC->SetStretchBltMode(COLORONCOLOR);
StretchDIBits(pDC->GetSafeHdc(),0,0,rect.Width(),rect.Height(),0,0,bmpwidth,bmpheight,pBmpbuf,pBmpInfo,DIB_RGB_COLORS,SRCCOPY);
}