关于MFC里面位图相关的操作
说实话,最近一段时间由于项目的关系,不得不和MFC里面的图形东西打交道。
在mfc里面感觉CBITMAP里面的一些函数像是被微软抛弃了,按部就班的创建一个24位图像却始终不能成功。
最后转向DIB来创建。
然后显示也是一样的,感觉MFC里面很多东西都被抛弃了,很多都不能成功。
下面是创建24位位图,并且将位图保存到bmp文件里面的代码:
CDC *pdeskdc = GetDesktopWindow()->GetWindowDC() ; CDC memdc;memdc.CreateCompatibleDC(pdeskdc);int nWidth = GetSystemMetrics(SM_CXSCREEN);int nHeight = GetSystemMetrics(SM_CYSCREEN); BITMAPINFO bi; ZeroMemory(&bi, sizeof(BITMAPINFO));bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);bi.bmiHeader.biWidth = nWidth;bi.bmiHeader.biHeight = nHeight;bi.bmiHeader.biPlanes = 1;bi.bmiHeader.biBitCount = 24;BITMAPINFOHEADER bih;memset( &bih , 0 , sizeof(bih) );HCURSOR hCursor = GetCursor();POINT ptCursor;GetCursorPos(&ptCursor);ICONINFO IconInfo = {0};if(GetIconInfo(hCursor, &IconInfo)){ptCursor.x -= IconInfo.xHotspot;ptCursor.y -= IconInfo.yHotspot;if(NULL != IconInfo.hbmMask)DeleteObject(IconInfo.hbmMask);if(NULL != IconInfo.hbmColor)DeleteObject(IconInfo.hbmColor);}bmp.m_hObject = ::CreateDIBSection(memdc.m_hDC, &bi, DIB_RGB_COLORS, (LPVOID*)&lpBitmapBits, NULL, 0);CBitmap *old = memdc.SelectObject(&bmp);memdc.BitBlt(0 , 0 , nWidth ,nHeight , pdeskdc , 0 , 0 , SRCCOPY);DrawIconEx(memdc.m_hDC, ptCursor.x, ptCursor.y, hCursor, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);int s;s = nWidth*3 %4 ;BITMAPFILEHEADER bh;ZeroMemory(&bh, sizeof(BITMAPFILEHEADER));bh.bfType = 0x4d42; //bitmap //bh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);bh.bfOffBits = 54 ; bh.bfSize = bh.bfOffBits + (nWidth*3+s)*nHeight;bi.bmiHeader.biCompression = BI_RGB ; bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);bi.bmiHeader.biSizeImage = (nWidth*3+s)*nHeight ; bih.biBitCount= 24 ;bih.biCompression= BI_RGB ;bih.biHeight=nHeight;bih.biPlanes=1;bih.biSize=sizeof(BITMAPINFOHEADER);bih.biSizeImage=(nWidth*3+s)*nHeight;bih.biWidth=nWidth;CFile file;if(file.Open(_TEXT("1.bmp"), CFile::modeCreate | CFile::modeWrite)){ file.Write(&bh, sizeof(BITMAPFILEHEADER));file.Write(&bih, sizeof(BITMAPINFOHEADER));//file.Write(lpBitmapBits, 3 * nWidth * nHeight);file.Write(lpBitmapBits, bih.biSizeImage);file.Close();}memdc.DeleteDC() ;
获取上面的代码一开始是用DDB方法,始终不能成功,最后转向DIB。
没有相关书籍作为指导,只能自己摸索。
然后通过 jpeg压缩,jpeg压缩算法不能使32位的图片,所以获取24位图片。
获取之后就是解压和显示了 。
显示的时候也是同样的问题,DDB始终不能成功,用DIB就可以,不知道里面到底是什么问题。
BITMAPINFO bin;memset(&bin , 0 , sizeof(BITMAPINFO) );bin.bmiHeader.biBitCount = 24 ; bin.bmiHeader.biHeight = 768 ; bin.bmiHeader.biPlanes = 1 ; bin.bmiHeader.biWidth = 1366;bin.bmiHeader.biSize = sizeof(BITMAPINFO);bin.bmiHeader.biSizeImage = (1366*3+2)*768;CRect re;GetWindowRect(&re);StretchDIBits( GetWindowDC()->m_hDC , 0,0,re.Width(),re.Height(),0,0,1366,768,data , &bin , DIB_RGB_COLORS , SRCCOPY );
就这几行代码就成功了 ,
但是如果用,cbitmap类里面的 createbitmap、setbitbls等函数,基本上是显示不了的。
原因不知道为什么,要是哪位知道可以告诉一下。
这其中页出现很多问题。
比如,保存32位位图的时候,只把bitmapinfo结构体里面的bincounts的值改成24位,其余的不变,大小还是按照32位的存进去,当你读取的时候,居然得到24位的图像。
微软搞得一些东西真是伤脑筋!