【MFC编程】屏幕截图,并保存成文件

获取屏幕位图代码:

HBITMAP CScreenShotDlg::GetScreenBitmap()
{
    HDC hSrcDc;
    HDC hMemDc;
    HBITMAP hBitmap;
    HBITMAP hOldBitmap;

    int nWidth; //!<有效宽度
    int nHeigth; //!<有效长度

    int m_nScreenW = GetSystemMetrics(SM_CXSCREEN);
    int m_nScreenH = GetSystemMetrics(SM_CYSCREEN);
    CRect rect(0, 0, m_nScreenW, m_nScreenH);

    int nX1 = v_lpRect->left;
    int nY1 = v_lpRect->top;
    int nX2 = v_lpRect->right;
    int nY2 = v_lpRect->bottom;
    nX1 = nX1 < 0 ? 0 : nX1;
    nY1 = nY1 < 0 ? 0 : nY1;
    nX2 = nX2 > m_nScreenW ? m_nScreenW : nX2;
    nY2 = nY2 > m_nScreenH ? m_nScreenH : nY2;
    nWidth = nX2 - nX1;
    if (nWidth < 0)
    {
        nWidth = abs(nWidth);
        nX1 = v_lpRect->right;
        nX2 = v_lpRect->left;
    }
    nHeigth = nY2 - nY1;
    if (nHeigth < 0)
    {
        nHeigth = abs(nHeigth);
        nY1 = v_lpRect->bottom;
        nY2 = v_lpRect->top;
    }

    //!<判断矩形是否为空矩形
    if (v_lpRect != NULL)
    {
        if ((v_lpRect->bottom - v_lpRect->top == 0)
            || (v_lpRect->left - v_lpRect->right == 0))
        {
            return NULL;
        }
    }
    //!<创建屏幕DC
    hSrcDc = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
    //!<创建屏幕兼容DC,默认1*1像素大小
    hMemDc = CreateCompatibleDC(hSrcDc);
    //!<创建屏幕兼容位图,为一个黑色背景位图
    hBitmap = CreateCompatibleBitmap(hSrcDc, nWidth, nHeigth);
    //!<将位图加载到内存DC,这样内存DC的大小就和屏幕大小一致了
    hOldBitmap = (HBITMAP)SelectObject(hMemDc, hBitmap);
    //!<直接拷贝,将内容拷贝到内存DC中
    BitBlt(hMemDc, 0, 0, nWidth, nHeigth, hSrcDc, nX1, nY1, SRCCOPY);
    //!<返回真正屏幕位图
    hBitmap = (HBITMAP)SelectObject(hMemDc, hOldBitmap);

    DeleteDC(hSrcDc);
    DeleteDC(hMemDc);

    return hBitmap;
}   

保存到文件代码:

BOOL CScreenShotDlg::SaveBitmapToFile( HBITMAP v_hBitmap, const char* v_szFileName )
{
    HDC hDC = NULL;
    int nBits = 0;
    WORD wBitCount = 0;

    hDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);           
    nBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
    DeleteDC(hDC);
    if (nBits <= 1)
    {
        wBitCount = 1;
    }
    else if (nBits <= 4)
    {
        wBitCount = 4;
    }
    else if (nBits <=8 )
    {
        wBitCount = 8;
    }
    else
    {
        wBitCount = 24;
    }

    DWORD dwPaletteSize = 0;
    if(wBitCount <= 8)//小于八位按八位处理
        dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD);

    BITMAP Bitmap;
    BITMAPINFOHEADER bmiHead;   //!<位图信息头结构  
    GetObject(v_hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
    bmiHead.biSize = sizeof(BITMAPINFOHEADER);
    bmiHead.biWidth = Bitmap.bmWidth;
    bmiHead.biHeight = Bitmap.bmHeight;
    bmiHead.biPlanes = 1;
    bmiHead.biBitCount = wBitCount;
    bmiHead.biCompression = BI_RGB;
    bmiHead.biSizeImage = 0;
    bmiHead.biXPelsPerMeter = 0;
    bmiHead.biYPelsPerMeter = 0;
    bmiHead.biClrUsed = 0;
    bmiHead.biClrImportant = 0;

    //!<位图中像素字节大小
    DWORD dwBmpBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32)* 4 * Bitmap.bmHeight;
    //!<为位图内容分配内存
    HANDLE hDib = GlobalAlloc(GHND, dwBmpBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
    LPBITMAPINFOHEADER lpbmiHead = (LPBITMAPINFOHEADER)GlobalLock(hDib);
    *lpbmiHead = bmiHead;

    //!<处理调色板
    HANDLE hPal = NULL;
    HANDLE hOldPal = NULL;
    hPal = GetStockObject(DEFAULT_PALETTE);
    if(hPal)
    {
        hDC = ::GetDC(NULL);
        hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
        RealizePalette(hDC);
    }

    //获取该调色板下新的像素值
    GetDIBits(hDC, v_hBitmap, 0, (UINT)Bitmap.bmHeight,
        (LPSTR)lpbmiHead + sizeof(BITMAPINFOHEADER) + dwPaletteSize,
        (BITMAPINFO*)lpbmiHead, DIB_RGB_COLORS);

    //恢复调色板
    if(hOldPal)
    {
        SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
        RealizePalette(hDC);
        ::ReleaseDC(NULL, hDC);
    }

    HANDLE hFile = CreateFile(v_szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if(hFile == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    //设置位图文件头
    BITMAPFILEHEADER bmfHead;//位图文件头结构
    bmfHead.bfType = 0x4d42;//"bm"
    DWORD dwDibSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 
        dwPaletteSize + dwBmpBitsSize;//位图文件大小
    bmfHead.bfSize = dwDibSize;
    bmfHead.bfReserved1 = 0;
    bmfHead.bfReserved2 = 0;
    bmfHead.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER)+ dwPaletteSize;

    //写入位图文件头
    DWORD dwWritten = 0;//写入文件字节数
    WriteFile(hFile, (LPSTR)&bmfHead, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
    //写入位图文件其余内容
    WriteFile(hFile, (LPSTR)lpbmiHead, dwDibSize, &dwWritten, NULL);

    //清除
    GlobalUnlock(hDib);
    GlobalFree(hDib);
    CloseHandle(hFile);

    return TRUE;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值