void CTestDIBView::OnFileSaveAs() 
{
// TODO: Add your command handler code here CClientDC dc(this);
CDC memDC;
CRect rect;
GetClientRect(rect);

memDC.CreateCompatibleDC(&dc);
int Width = rect.Width();
int Height = rect.Height();
int iBits; //当前显示分辨率下每个像素所占字节数
WORD wBitCount; ////位图中每个像素所占字节数
DWORD dwPaletteSize=0, dwBmBitsSize;//定义调色板大小,位图中像素字节大小 if(m_OpenState != 1)
{
m_bitmap.CreateCompatibleBitmap(&dc, Width, Height);
}
CBitmap* pOld = memDC.SelectObject(&m_bitmap);
memDC.BitBlt(0, 0, Width, Height, &dc, 0, 0, SRCCOPY);
memDC.SelectObject(pOld);
BITMAP btm;
m_bitmap.GetBitmap(&btm);
DWORD dwBytesSize  = btm.bmWidthBytes * btm.bmHeight;
iBits = GetDeviceCaps(memDC, BITSPIXEL);

if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else if (iBits <= 24)
wBitCount = 24;
//计算调色板大小
if (wBitCount <= 8)
dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);
///////////////////////////////////////////// 
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
HANDLE hPal,hOldPal=NULL;  bih.biBitCount = wBitCount;//btm.bmBitsPixel;
bih.biClrImportant = 0;
bih.biClrUsed = 0;
bih.biCompression = BI_RGB;
bih.biHeight = btm.bmHeight;
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = dwBytesSize ;
bih.biWidth = btm.bmWidth;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bfh.bfReserved1 = bfh.bfReserved2 = 0;
bfh.bfType = 0x4D42; // bm  dwBmBitsSize = ((btm.bmWidth*wBitCount+31)/32)*4*btm.bmHeight;
LPSTR lpData = (LPSTR)GlobalAlloc(GPTR, dwBmBitsSize );    //// 处理调色板 
hPal = GetStockObject(DEFAULT_PALETTE); 
if (hPal) 

dc.m_hDC = ::GetDC(NULL); 
hOldPal = ::SelectPalette(dc, (HPALETTE)hPal, FALSE); 
RealizePalette(dc); 
}
//// 获取该调色板下新的像素值
GetDIBits(dc,m_bitmap,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);
////恢复调色板 
if (hOldPal) 

::SelectPalette(dc, (HPALETTE)hOldPal, TRUE); 
RealizePalette(dc); 
::ReleaseDC(NULL, dc); 
}      

bfh.bfSize =sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize; 
bfh.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize; CFileDialog dlg(FALSE,NULL,NULL,NULL,_T("位图文件(*.bmp)|*.bmp|"));
if (dlg.DoModal()!=IDOK)
return;

CFile  bf;
szSaveFileName=dlg.GetPathName() + ".bmp";
if(bf.Open(szSaveFileName, CFile::modeCreate | CFile::modeWrite))
{
bf.WriteHuge(&bfh, sizeof(BITMAPFILEHEADER));
bf.WriteHuge(&bih, sizeof(BITMAPINFOHEADER));
bf.WriteHuge(lpData,dwBmBitsSize);
bf.Close();
AfxMessageBox("保存成功");
}
GlobalFree(lpData); 
memDC.DeleteDC();
}
我最近写的一个程序的代码
可以实现你的要求
给你参考下

解决方案 »

  1.   

    请问你的代码里面:
    m_bitmap、m_OpenState是什么意思?
    对了,程序运行到bf.WriteHuge(lpData,dwBmBitsSize);就会提示错误
      

  2.   

    m_bitmap是CBitmap类的对象 m_OpenState表示有没有开图 ,如果没有开图就初始化位图,如果你已经打开了一张图,则不需要初始化
      

  3.   

    对了,程序运行到bf.WriteHuge(lpData,dwBmBitsSize);就会提示错误
    可能是因为lpData内存没有分配成功
    你可以试着改成  wBitCount = btm.bmBitsPixel
    然后再加判断 else if (iBits <= 32)
                     wBitCount = 32;