最基本的方法,自己填充文件结构,比如,
如果m_hDib是你的句柄
LPBITMAPINFOHEADER lpBI;
BITMAPFILEHEADER bmfHdr;
lpBI = (LPBITMAPINFOHEADER)GlobalLock(m_hDib);
bmfHdr.bfType = DIB_HEADER_MARKER;dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPBYTE)lpBI);if((lpBI->biCompression == BI_RLE8)||(lpBI->biCompression == BI_RLE4))
   dwDIBSize += lpBI->biSizeImage;
else
{
DWORD dwBmBitsSize;
dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount*lpBI->biHeight;
dwDIBSize += dwBmBitsSize;
lpBI->biSizeImage;
}bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize + PaletteSize((LPBYTE)lpBI);TRY
{
pFile->Write(&bmfHdr,sizeof(BITMAPFILEHEADER));
//write DIB buffer;
pFile->WriteHuge(lpBI,dwDIBSize);
}
CATCH(CException, e)
{
GlobalUnlock(m_hDib);
return FALSE;
}END_CATCHGlobalUnlock(m_hDib);

解决方案 »

  1.   

    你是不是老谢呀,这个函数我已经写好了。在8b、16b、24b、32b下调试通过。
    用法:
    CBitmap cBitmap;
    cBitmap.LoadBitmap(IDB_BITMAP2);
    SaveToBmp(cBitmap,"d:\\test.bmp");
    #include "math.h"
    BOOL SaveToBmp(HBITMAP hBitmap,const char *szBmpFile)
    {
    BITMAP bm;
    PBITMAPINFO bmpInf;
    BOOL bRet=FALSE;
    int nPaletteSize=0; if(GetObject(hBitmap,sizeof(bm),&bm)==0)
    return FALSE; if(bm.bmBitsPixel<16)
    nPaletteSize=pow(2,bm.bmBitsPixel); bmpInf=(PBITMAPINFO)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)+
    sizeof(RGBQUAD)*nPaletteSize);

    if(bmpInf==NULL)
    {
    return FALSE;
    }

    //-----------------------------------------------
    bmpInf->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpInf->bmiHeader.biWidth = bm.bmWidth;
    bmpInf->bmiHeader.biHeight = bm.bmHeight;
    bmpInf->bmiHeader.biPlanes = bm.bmPlanes;
    bmpInf->bmiHeader.biBitCount = bm.bmBitsPixel;
    bmpInf->bmiHeader.biCompression = BI_RGB;
    bmpInf->bmiHeader.biSizeImage = (bm.bmWidth+7)/8*bm.bmHeight*bm.bmBitsPixel;
    bmpInf->bmiHeader.biXPelsPerMeter = 0;
    bmpInf->bmiHeader.biYPelsPerMeter = 0;
    bmpInf->bmiHeader.biClrUsed = 0;
    bmpInf->bmiHeader.biClrImportant = 0;
    //-----------------------------------------------

    void* buf=(void*) new char[bmpInf->bmiHeader.biSizeImage];
    if(buf==NULL)
    {
    LocalFree(bmpInf);
    return FALSE;
    }

    if(!::GetDIBits(GetWindowDC(NULL),hBitmap,0,(WORD)bm.bmHeight,buf,bmpInf,DIB_RGB_COLORS))
    {
    delete []buf;
    LocalFree(bmpInf);
    return FALSE;
    }


    BITMAPFILEHEADER bmFHeader;
    bmFHeader.bfType=0x4d42;
    bmFHeader.bfReserved1=0;
    bmFHeader.bfReserved2=0;
    bmFHeader.bfOffBits=(DWORD)(sizeof(BITMAPFILEHEADER)+bmpInf->bmiHeader.biSize+
    nPaletteSize*sizeof(RGBQUAD));

    bmFHeader.bfSize=(DWORD)(bmFHeader.bfOffBits+bmpInf->bmiHeader.biSizeImage); DWORD dwTemp;
    HANDLE hFile;
    hFile=CreateFile(szBmpFile,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,NULL);

    while(hFile!=INVALID_HANDLE_VALUE)
    {
    //写BITMAPFILEHEADER
    if(WriteFile(hFile,&bmFHeader,sizeof(BITMAPFILEHEADER),&dwTemp,NULL)==0)
    break;

    //写BITMAPINFOHEADER
    if(WriteFile(hFile,&bmpInf->bmiHeader,bmpInf->bmiHeader.biSize,&dwTemp,NULL)==0)
    break

    //写调色板数据(可能有)
    if(WriteFile(hFile,&bmpInf->bmiColors,nPaletteSize*sizeof(RGBQUAD),&dwTemp,NULL)==0)
    break; //写图像数据
    DWORD dwLen=bmpInf->bmiHeader.biSizeImage;
    BYTE *pTemp=(BYTE*)buf;
    while(dwLen>=65535)
    {
    if(WriteFile(hFile,pTemp,65535,&dwTemp,NULL)==0)
    {
    dwLen=0xffffffff;
    break;
    }
    dwLen-=65535;
    pTemp+=65535;
    }

    if(dwLen==0xffffffff)
    break; if((dwLen>0)&&(WriteFile(hFile,pTemp,dwLen,&dwTemp,NULL)==0))
    break; bRet=TRUE; break;//必须的
    }

    if(hFile!=INVALID_HANDLE_VALUE)
    {
    CloseHandle(hFile);
    } delete []buf;
    LocalFree(bmpInf);
    return bRet;
    }