自定义DC的RECT保存为bmp文件

来源:互联网 发布:tensorflow 英文官网 编辑:程序博客网 时间:2024/04/28 18:26

在截图技术中广泛采用

 

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 );
    // 创建一个与屏幕设备描述表兼容的位图
    hBitmap = CreateCompatibleBitmap( hScrDC, nWidth, nHeight );
    // 把新位图选到内存设备描述表中
    hOldBitmap = ( HBITMAP )SelectObject( hMemDC, hBitmap );
    // 把屏幕设备描述表拷贝到内存设备描述表中
    StretchBlt( hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, nWidth, nHeight, SRCCOPY );
    //得到屏幕位图的句柄
    hBitmap = ( HBITMAP )SelectObject( hMemDC, hOldBitmap );
    //清除
    DeleteDC( hMemDC );
    DeleteObject( hOldBitmap );
    //返回位图句柄
    return hBitmap;

}


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("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;


}

原创粉丝点击