c/c++将HBITMAP数据保存成BMP图片的方式

by 好大一小白 2010.12.1 21:22

取得HBITMAP数据后,需要自己写BMP头才可以保存成图片文件。下面提供具体代码:
 

//创建一个BMP文件头对象  
PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp)  
{  
    BITMAP bmp;   
    PBITMAPINFO pbmi;   
    WORD    cClrBits;   
 
    // Retrieve the bitmap color format, width, and height.   
    if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))   
        return NULL; 
 
    // Convert the color format to a count of bits.   
    cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);   
    if (cClrBits == 1)   
        cClrBits = 1;   
    else if (cClrBits <= 4)   
        cClrBits = 4;   
    else if (cClrBits <= 8)   
        cClrBits = 8;   
    else if (cClrBits <= 16)   
        cClrBits = 16;   
    else if (cClrBits <= 24)   
        cClrBits = 24;   
    else cClrBits = 32;   
 
    // Allocate memory for the BITMAPINFO structure. (This structure   
    // contains a BITMAPINFOHEADER structure and an array of RGBQUAD   
    // data structures.)   
 
     if (cClrBits != 24)   
         pbmi = (PBITMAPINFO) LocalAlloc(LPTR,   
                    sizeof(BITMAPINFOHEADER) +   
                    sizeof(RGBQUAD) * (1<< cClrBits));   
 
     // There is no RGBQUAD array for the 24-bit-per-pixel format.   
 
     else   
         pbmi = (PBITMAPINFO) LocalAlloc(LPTR,   
                    sizeof(BITMAPINFOHEADER));   
 
    // Initialize the fields in the BITMAPINFO structure.   
 
    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);   
    pbmi->bmiHeader.biWidth = bmp.bmWidth;   
    pbmi->bmiHeader.biHeight = bmp.bmHeight;   
    pbmi->bmiHeader.biPlanes = bmp.bmPlanes;   
    pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;   
    if (cClrBits < 24)   
        pbmi->bmiHeader.biClrUsed = (1<<cClrBits);   
 
    // If the bitmap is not compressed, set the BI_RGB flag.   
    pbmi->bmiHeader.biCompression = BI_RGB;   
 
    // Compute the number of bytes in the array of color   
    // indices and store the result in biSizeImage.   
    // For Windows NT, the width must be DWORD aligned unless   
    // the bitmap is RLE compressed. This example shows this.   
    // For Windows 95/98/Me, the width must be WORD aligned unless the   
    // bitmap is RLE compressed.  
    pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8  
                                  * pbmi->bmiHeader.biHeight;   
    // Set biClrImportant to 0, indicating that all of the   
    // device colors are important.   
     pbmi->bmiHeader.biClrImportant = 0;   
     return pbmi;   

 

BOOL SaveHBITMAP2File(HWND hwnd, LPTSTR pszFile, HBITMAP hBMP, HDC hDC)  
{  
    PBITMAPINFO pbi = CreateBitmapInfoStruct(hwnd, hBMP);  
 
    HANDLE hf;                 // file handle   
    BITMAPFILEHEADER hdr;       // bitmap file-header   
    PBITMAPINFOHEADER pbih;     // bitmap info-header   
    LPBYTE lpBits;              // memory pointer   
    DWORD dwTotal;              // total count of bytes   
    DWORD cb;                   // incremental count of bytes   
    BYTE *hp;                   // byte pointer   
    DWORD dwTmp;   
 DWORD fileSizeInfo=0;
 
    pbih = (PBITMAPINFOHEADER) pbi;   
    lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);  
 
    if (!lpBits)   
         return FALSE; 
 
    // Retrieve the color table (RGBQUAD array) and the bits   
    // (array of palette indices) from the DIB.   
    if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,   
        DIB_RGB_COLORS))   
    {  
         return FALSE;   
    }  
 
    // Create the .BMP file.  
 fileSizeInfo = (DWORD) (sizeof(BITMAPFILEHEADER) +   
                 pbih->biSize + pbih->biClrUsed   
                 * sizeof(RGBQUAD) + pbih->biSizeImage);
 if(fileSizeInfo==58)
  return FALSE;    //blank
    hf = CreateFile(pszFile,   
                   GENERIC_READ | GENERIC_WRITE,   
                   (DWORD) 0,   
                    NULL,   
                   OPEN_ALWAYS,   
                   FILE_ATTRIBUTE_NORMAL,   
                   (HANDLE) NULL);   
    if (hf == INVALID_HANDLE_VALUE)   
         return FALSE;   
    hdr.bfType = 0x4d42;        // 0x42 = "B" 0x4d = "M"   
    // Compute the size of the entire file.   
    hdr.bfSize = fileSizeInfo; 
 
    hdr.bfReserved1 = 0;   
    hdr.bfReserved2 = 0;   
 
    // Compute the offset to the array of color indices.   
    hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +   
                    pbih->biSize + pbih->biClrUsed   
                    * sizeof (RGBQUAD);   
 
    // Copy the BITMAPFILEHEADER into the .BMP file.   
    if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),   
        (LPDWORD) &dwTmp,  NULL))   
    {  
         return FALSE;   
    }  
 
    // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.   
    if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)   
                  + pbih->biClrUsed * sizeof (RGBQUAD),   
                  (LPDWORD) &dwTmp, ( NULL)))  
    {  
         return FALSE; 
    }  
          
 
    // Copy the array of color indices into the .BMP file.   
    dwTotal = cb = pbih->biSizeImage;   
    hp = lpBits;   
    if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL))   
    {  
         return FALSE;   
    }  
 
    // Close the .BMP file.   
     if (!CloseHandle(hf))   
         return FALSE;   
 
    // Free memory.   
    GlobalFree((HGLOBAL)lpBits);   
    return TRUE;  
}  


调用 :
SaveHBITMAP2File(NULL,fileP,destBmp,destDc);

Tags: , , , , ,

VC++ | 常用工具 | 工具

不允许评论

微信赞

本站统计

36 篇文章
5 个单页
12 条评论
12 次评分
1345408 次访问
访问统计开始于 2010年4月24日
平均日访问 224 次
当前 4 人在线

声明

本博所有网友评论不代表本博立场,版权归其作者所有。 
苏ICP备09004001号
Powered by BlogYi.net  edit by 1wanweb.com
© Copyright 2008-2017