您的位置:首页 > 其它

关于MFC里面位图相关的操作

2012-10-28 16:23 357 查看
说实话,最近一段时间由于项目的关系,不得不和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位的图像。

微软搞得一些东西真是伤脑筋!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: