说实话,最近一段时间由于项目的关系,不得不和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位的图像。
微软搞得一些东西真是伤脑筋!