win7 64 vs2010
使用vs2010 创建一个MFC 对话框 添加 两个按钮,其实两个按钮的 实现的代码 类似 ,只是 分配内存的地方
一个是用的malloc ,一个是用的HeapAlloc。
看一下具体一个按钮的点击事件:
void CbmpTestBDlg::OnBnClickedBtnBmpTest()
{
// TODO: 在此添加控件通知处理程序代码
CString strFileName;
CString strPathName ;
LPTSTR lpstrPath = NULL;
TCHAR tszTempPath[_MAX_PATH];
ZeroMemory(tszTempPath, MAX_PATH);
GetCurrentDirectory(MAX_PATH, tszTempPath);
lpstrPath = tszTempPath;
CFileDialog filedlg(TRUE, NULL, NULL,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("图像(*.bmp)|*.bmp"));
filedlg.m_ofn.lpstrInitialDir=lpstrPath ; //打开当前文件夹所在目录
if (filedlg.DoModal() == IDOK){
strFileName = filedlg.GetFileName();
strPathName = filedlg.GetPathName();
}
else{
return;
}
printf("strFileName : %S\r\n",strFileName.GetString());
printf("strPathName : %S\r\n",strPathName.GetString());
int numQuad; //调色板的数量
int flag; //是否已打开文件
int LineBytes; //LineBytes为每一行的字节数
BITMAPINFO* pbi; //BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1];
BYTE* lpBuf; //像素数据 B G R 0
RGBQUAD * quad; //调色板,每个4字节
BITMAPINFOHEADER bi;//文件信息 40字节
BITMAPFILEHEADER bf;//文件头 14字节
CString filename;
CFile file;
BOOL bResult;
filename=strPathName;
printf("filename : %S\r\n",filename.GetString());
if(file.Open(filename,CFile::modeRead|CFile::shareDenyNone,NULL)==)
{ //读取文件失败
AfxMessageBox(L"无法打开文件!",MB_OK,);
return ;
}
else
{ file.Read(&bf,sizeof(bf)); //读取文件头,14字节
if(bf.bfType!=)
{ AfxMessageBox(L"非位图,打开失败!",MB_OK,);
return ;
}
if(file.GetLength()!=bf.bfSize)
{
AfxMessageBox(L"文件损坏,打开失败!",MB_OK,);
return ;
}
//读取文件信息
file.Read(&bi,sizeof(bi));
printf("bi.biBitCount =%d\r\n",bi.biBitCount);
if(bi.biBitCount>=) //真彩色24或32位,如真彩色图,是不需要调色板的,BITMAPINFOHEADER后直接是位图数据
{
numQuad=;
}
else //2的bi.biBitCount次幂,
{
numQuad=<<bi.biBitCount;
}
quad=(RGBQUAD*)malloc(numQuad*sizeof(RGBQUAD));
printf("quad = 0x%x\r\n",quad);
memset(quad,,numQuad*sizeof(RGBQUAD));
if(numQuad!=){
file.Read(quad,sizeof(RGBQUAD)*numQuad);
}
pbi=(BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD));
printf("pbi = 0x%x\r\n",pbi);
printf("numQuad = %d \r\n",numQuad);
memset(pbi,,sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD));
memcpy(pbi,&bi,sizeof(bi));
if(numQuad > ){
pbi->bmiColors->rgbRed = ;
pbi->bmiColors->rgbBlue = ;
pbi->bmiColors->rgbGreen = ;
}
// memcpy(pbi+sizeof(bi),quad,numQuad*sizeof(RGBQUAD));
//LineBytes为每一行的字节数
LineBytes=(DWORD)(bi.biWidth*bi.biBitCount+)*/;
//读取数据
bi.biSizeImage=bf.bfSize-bf.bfOffBits;
lpBuf=(BYTE*)malloc(bi.biSizeImage);
printf("lpBuf = 0x%x\r\n",lpBuf);
memset(lpBuf,,bi.biSizeImage);
file.Read(lpBuf,bi.biSizeImage);
//关闭文件
file.Close();
flag=; //文件已读取标志
}
CDC *pDC = GetDC();
printf("bi.biWidth = %d\r\n",bi.biWidth);
printf("bi.biHeight = %d\r\n",bi.biHeight);
if(flag==) //显示位图
{
SetDIBitsToDevice(pDC->m_hDC,,,bi.biWidth,bi.biHeight,,,,bi.biHeight,lpBuf,pbi,DIB_RGB_COLORS);
}
free(quad);
free(pbi);
free(lpBuf);
}
运行例子1:

运行log:
strFileName : UserImages.bmp
strPathName : E:\VC\workplace\bmpTestB\bmpTestB\UserImages.bmp
filename : E:\VC\workplace\bmpTestB\bmpTestB\UserImages.bmp
bi.biBitCount =24
quad = 0x26b75a8
pbi = 0x2addd78
numQuad = 0
lpBuf = 0x2adffe8
bi.biWidth = 176
bi.biHeight = 15
该图片原图名字为:UserImages.bmp,这个是一个24位的BMP图片。没有调色板。
原图截图如下:(需要原始图片的,请到最后的代码工程下载链接中去找)
运行例子2:
运行log 如下:
Hello
strFileName : Kitty.bmp
strPathName : E:\VC\workplace\bmpTestB\bmpTestB\Kitty.bmp
filename : E:\VC\workplace\bmpTestB\bmpTestB\Kitty.bmp
bi.biBitCount =1
quad = 0xb0fc20
pbi = 0x9bf120
numQuad = 2
lpBuf = 0xb0fc58
bi.biWidth = 101
bi.biHeight = 46
该图片原图名字为:Kitty.bmp,这个是一个单色的BMP图片。有调色板。
原图截图如下:(需要原始图片的,请到最后的代码工程下载链接中去找)
工程源代码:
https://download.csdn.net/download/wowocpp/10496451
遇到问题:
1, 如果 printf 打印CString的值:
2,例子2 中显示的 单色BMP图 是 反显的
这个方法应该不是很正规。
3, 0x000000 表示 黑色,0xFFFFFF 表示白色
参考网址:
DIB函数注释
https://blog.csdn.net/u012934099/article/details/23052089