就是处理完图像以后另存bmp图像文件?

解决方案 »

  1.   

    HANDLE CWrapBitmap::DDBToDIB(CBitmap &bitmap, DWORD dwCompression, CPalette *pPal)
    {
    BITMAP bm;
    BITMAPINFOHEADER bi;
    LPBITMAPINFOHEADER  lpbi;
    DWORD dwLen;
    HANDLE handle;
    HANDLE hDIB;
    HDC  hDC;
    HPALETTE hPal;
    ASSERT( bitmap.GetSafeHandle() ); // The function has no arg for bitfields
    if( dwCompression == BI_BITFIELDS )
    return NULL; // If a palette has not been supplied use defaul palette
    hPal = (HPALETTE) pPal->GetSafeHandle();
    if (hPal==NULL)
    hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); // Get bitmap information
    bitmap.GetObject(sizeof(bm),(LPSTR)&bm); //>> 填充位图信息头 bitmapinfoheader
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bm.bmWidth;
    bi.biHeight  = bm.bmHeight;
    bi.biPlanes  = 1;
    bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel;
    bi.biCompression = dwCompression;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;
    //<< // Compute the size of the  infoheader and the color table
    int nColors = (1 << bi.biBitCount);
    if( nColors > 256 ) 
    nColors = 0;
    dwLen  = bi.biSize + nColors * sizeof(RGBQUAD); // We need a device context to get the DIB from
    hDC = GetDC(NULL);
    hPal = SelectPalette(hDC,hPal,FALSE);
    RealizePalette(hDC); // Allocate enough memory to hold bitmapinfoheader and color table
    hDIB = GlobalAlloc(GMEM_FIXED,dwLen); if (!hDIB){
    SelectPalette(hDC,hPal,FALSE);
    ReleaseDC(NULL,hDC);
    return NULL;
    } lpbi = (LPBITMAPINFOHEADER)hDIB; *lpbi = bi; // Call GetDIBits with a NULL lpBits param, so the device driver 
    // will calculate the biSizeImage field 
    GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
    (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS); bi = *lpbi; // If the driver did not fill in the biSizeImage field, then compute it
    // Each scan line of the image is aligned on a DWORD (32bit) boundary
    if (bi.biSizeImage == 0){
    bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) 
    * bi.biHeight; // If a compression scheme is used the result may infact be larger
    // Increase the size to account for this.
    if (dwCompression != BI_RGB)
    bi.biSizeImage = (bi.biSizeImage * 3) / 2;
    } // Realloc the buffer so that it can hold all the bits
    dwLen += bi.biSizeImage;
    if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
    hDIB = handle;
    else{
    GlobalFree(hDIB); // Reselect the original palette
    SelectPalette(hDC,hPal,FALSE);
    ReleaseDC(NULL,hDC);
    return NULL;
    } // Get the bitmap bits
    lpbi = (LPBITMAPINFOHEADER)hDIB; // FINALLY get the DIB
    BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
    0L, // Start scan line
    (DWORD)bi.biHeight, // # of scan lines
    (LPBYTE)lpbi  // address for bitmap bits
    + (bi.biSize + nColors * sizeof(RGBQUAD)),
    (LPBITMAPINFO)lpbi, // address of bitmapinfo
    (DWORD)DIB_RGB_COLORS); // Use RGB for color table if( !bGotBits )
    {
    GlobalFree(hDIB);

    SelectPalette(hDC,hPal,FALSE);
    ReleaseDC(NULL,hDC);
    return NULL;
    } SelectPalette(hDC,hPal,FALSE);
    ReleaseDC(NULL,hDC);
    return hDIB;
    }BOOL CWrapBitmap::Save(LPCTSTR lpszPathName)
    {
    HANDLE hDIB;

    if(!m_hBitmap)
    return FALSE;
    hDIB=DDBToDIB(m_Bitmap,BI_RGB,NULL); //转化DDB2DIB if( hDIB == NULL )
    return FALSE;
    // Write it to file
    BITMAPFILEHEADER hdr; //位图文件头
    LPBITMAPINFOHEADER lpbi; //位图信息头 CFile file; if( !file.Open( lpszPathName, CFile::modeWrite|CFile::modeCreate) )
    return FALSE; lpbi = (LPBITMAPINFOHEADER)hDIB; int nColors = 1 << lpbi->biBitCount; // Fill in the fields of the file header 
    hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM"
    hdr.bfSize = GlobalSize (hDIB) + sizeof( hdr );
    hdr.bfReserved1  = 0; //保留字
    hdr.bfReserved2  = 0; //保留字
    hdr.bfOffBits = (DWORD) (sizeof( hdr ) + lpbi->biSize +
    nColors * sizeof(RGBQUAD)); // Write the file header 
    file.Write( &hdr, sizeof(hdr) ); // Write the DIB header and the bits 
    file.Write( lpbi, GlobalSize(hDIB) );

    file.Flush();
    file.Close(); // Free the memory allocated by DDBToDIB for the DIB
    GlobalFree( hDIB );
    return TRUE;
    }
      

  2.   

    我这几天也正在做位图方面的,找到了这个函数,可以保存位图。我有个问题,就是如何创建一个位图然后用鼠标在上面画完后保存下来呢?像WINDOWS中的画图函数一样呢?int SaveBitmapToFile(HBITMAP hBitmap, const char* lpFileName)
    {      
    HDC hDC; //设备描述表
    int iBits; //当前显示分辨率下每个像素所占字节数
    WORD wBitCount; //位图中每个像素所占字节数

    //定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
    DWORD dwPaletteSize=0;
    DWORD dwBmBitsSize;
    DWORD dwDIBSize, dwWritten; BITMAP Bitmap;         //位图属性结构
    BITMAPFILEHEADER bmfHdr;         //位图文件头结构
    BITMAPINFOHEADER bi;             //位图信息头结构 
    LPBITMAPINFOHEADER lpbi;           //指向位图信息头结构

    HANDLE fh, hDib, hPal,hOldPal=NULL; //定义文件,分配内存句柄,调色板句柄

    //计算位图文件每个像素所占字节数
    hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
    iBits = GetDeviceCaps(hDC, BITSPIXEL) * 
    GetDeviceCaps(hDC, PLANES);
    DeleteDC(hDC);
       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);

    //设置位图信息头结构
    GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
    bi.biSize            = sizeof(BITMAPINFOHEADER);
    bi.biWidth           = Bitmap.bmWidth;
    bi.biHeight          = Bitmap.bmHeight;
    bi.biPlanes          = 1;
    bi.biBitCount        = 24;
    bi.biCompression     = BI_RGB;
    bi.biSizeImage       = 0;
    bi.biXPelsPerMeter   = 0;
    bi.biYPelsPerMeter   = 0;
    bi.biClrUsed         = 0;
    bi.biClrImportant    = 0;

    dwBmBitsSize = ((Bitmap.bmWidth *
    wBitCount+31)/32)* 4
    *Bitmap.bmHeight ; //为位图内容分配内存
    hDib  = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
    *lpbi = bi; // 处理调色板   
    hPal = GetStockObject(DEFAULT_PALETTE);
    if (hPal)
    {
    hDC  = GetDC(NULL);
    hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
    RealizePalette(hDC);
    } // 获取该调色板下新的像素值
    GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
    (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,
    (BITMAPINFO*)lpbi, DIB_RGB_COLORS); //恢复调色板   
    if (hOldPal)
    {
    SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
    RealizePalette(hDC);
    ReleaseDC(NULL, hDC);
    } //创建位图文件    
    fh = CreateFile(lpFileName, GENERIC_WRITE, 
    0, NULL, CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if (fh == INVALID_HANDLE_VALUE)
    return FALSE; // 设置位图文件头
    // bmfHdr.bfType = 0x4D42;  // "BM"
    bmfHdr.bfType = (WORD)('M'<<8|'B');  // "BM"
    dwDIBSize    = sizeof(BITMAPFILEHEADER) 
    + sizeof(BITMAPINFOHEADER)
    + dwPaletteSize + dwBmBitsSize;  
    bmfHdr.bfSize = dwDIBSize;
    bmfHdr.bfReserved1 = 0;
    bmfHdr.bfReserved2 = 0;
    bmfHdr.bfOffBits = (DWORD)sizeof
    (BITMAPFILEHEADER) 
    + (DWORD)sizeof(BITMAPINFOHEADER)
    + dwPaletteSize; // 写入位图文件头
    WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), 
    &dwWritten, NULL); // 写入位图文件其余内容
    WriteFile(fh, (LPSTR)lpbi, dwDIBSize, 
    &dwWritten, NULL); //清除   
    GlobalUnlock(hDib);
    GlobalFree(hDib);
    CloseHandle(fh);
    return TRUE;
    }
      

  3.   

    http://www.codeproject.com/bitmap/dibsection.asp