把HDC保存成图片

先调用CopyDCToBitmap把HDC转成HBITMAP, 然后调用 SaveBmpSaveImg

BOOL SaveBmp (HBITMAP hBitmap, CString FileName)
{
    HDC   hDC;
    //当前分辨率下每象素所占字节数  
    int   iBits;
    //位图中每象素所占字节数  
    WORD  wBitCount;
    //定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数
    DWORD dwPaletteSize = 0, dwBmBitsSize = 0, dwDIBSize = 0, dwWritten = 0;
    //位图属性结构    
    BITMAP   Bitmap;
    //位图文件头结构  
    BITMAPFILEHEADER   bmfHdr;
    //位图信息头结构    
    BITMAPINFOHEADER   bi;
    //指向位图信息头结构      
    LPBITMAPINFOHEADER lpbi;
    //定义文件,分配内存句柄,调色板句柄    
    HANDLE  fh, hDib, hPal, hOldPal = NULL;

    //计算位图文件每个像素所占字节数    
    hDC = CreateDC(_T("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 wBitCount = 24;

    GetObject(hBitmap, sizeof(Bitmap), (LPSTR)& Bitmap);
    bi.biSize = sizeof( BITMAPINFOHEADER);
    bi.biWidth = Bitmap. bmWidth;
    bi.biHeight = Bitmap. bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount = wBitCount;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrImportant = 0;
    bi.biClrUsed = 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);
        //hDC   =   m_pDc->GetSafeHdc();  
        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( FileName, 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;
    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;
}


// 保存成JPG文件
BOOL SaveImg (HBITMAP hBitmap, CString imgFile)
{
    BITMAP bm;
    int width, height;
    GetObject(hBitmap, sizeof(BITMAP), & bm);
    width = bm.bmWidth;
    height = bm.bmHeight;
    CDC memDC;
    memDC.CreateCompatibleDC( NULL);
    memDC.SelectObject(hBitmap);

    CImage image;
    image.Create(width, height, 32);
    BitBlt( image. GetDC(), 0, 0, width, height, memDC. m_hDC, 0, 0, SRCCOPY );

    HRESULT hResult = image. Save(imgFile );
    //image.Save(_T("new.bmp"), Gdiplus::ImageFormatBMP);   // 保存成bmp

    image.ReleaseDC();
    memDC.DeleteDC();
    return SUCCEEDED( hResult);
}


HBITMAP CopyDCToBitmap (HDC hScrDC, LPRECT lpRect)
{
    HDC  hMemDC;
    //   屏幕和内存设备描述表  
    HBITMAP hBitmap, hOldBitmap;
    //   位图句柄  
    int  nX, nY, nX2, nY2;
    //   选定区域坐标  
    int  nWidth, nHeight;
    //   位图宽度和高度  

    //   确保选定区域不为空矩形  
    if (IsRectEmpty( lpRect))
        return   NULL;

    //   获得选定区域坐标  
    nX = lpRect->left;
    nY = lpRect->top;
    nX2 = lpRect->right;
    nY2 = lpRect->bottom;
    nWidth = nX2 - nX;
    nHeight = nY2 - nY;
    //   为屏幕设备描述表创建兼容的内存设备描述表  
    hMemDC = CreateCompatibleDC( hScrDC);
    //   创建一个与屏幕设备描述表兼容的位图,函数需要与CreateCompatibleDC配合使用  
    hBitmap = CreateCompatibleBitmap( hScrDC, nWidth, nHeight);
    //   把新位图选到内存设备描述表中  
    hOldBitmap = ( HBITMAP)SelectObject (hMemDC , hBitmap );
    //   把屏幕设备描述表拷贝到内存设备描述表中
    //   StretchBlt函数从源矩形中复制一个位图到目标矩形,必要时按目前目标设备设置的模式进行图像的拉伸或压缩。
    StretchBlt( hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, nWidth, nHeight, SRCCOPY);  // SRCCOPY
    //BitBlt(hMemDC,   0,   0,   nWidth,   nHeight,hScrDC,   nX,   nY,   SRCCOPY);  
    //   得到屏幕位图的句柄    

    hBitmap = (HBITMAP) SelectObject(hMemDC , hOldBitmap );
    //   清除    

    //DeleteDC(hScrDC);  
    DeleteDC( hMemDC);
    DeleteObject( hOldBitmap);
    //   返回位图句柄  
    return   hBitmap;
}
本文为“技术点滴”的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注