天天看点

win32 MFC 对话框 显示 BMP 文件(二) 可显示单色BMP图

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:

win32 MFC 对话框 显示 BMP 文件(二) 可显示单色BMP图

运行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图片。没有调色板。

原图截图如下:(需要原始图片的,请到最后的代码工程下载链接中去找)

win32 MFC 对话框 显示 BMP 文件(二) 可显示单色BMP图

运行例子2:

win32 MFC 对话框 显示 BMP 文件(二) 可显示单色BMP图

运行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图片。有调色板。

原图截图如下:(需要原始图片的,请到最后的代码工程下载链接中去找)

win32 MFC 对话框 显示 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