如何捕获部分屏幕并将其保存为BMP

How to capture part of the screen and save it to a BMP?

本文关键字:保存 BMP 何捕获 屏幕      更新时间:2023-10-16

可能重复:
如何在c++中用win32制作屏幕截图?

我目前正在尝试创建一个应用程序,将屏幕的一部分保存为bmp。我找到了BitBlt,但我真的不知道该怎么办。我试着搜索了一些答案,但我仍然没有用C++找到一个明确的答案。

所以,基本上我想要这个功能:

bool capturePartScreen(int x, int y, int w int, h, string dest){
    //Capture part of screen according to coordinates, width and height.
    //Save that captured image as a bmp to dest.
    //Return true if success, false if failure
}

BitBlt:

BOOL BitBlt(
    __in  HDC hdcDest,
    __in  int nXDest,
    __in  int nYDest,
    //The three above are the ones I don't understand!
    __in  int nWidth,
    __in  int nHeight,
    __in  HDC hdcSrc,
    __in  int nXSrc,
    __in  int nYSrc,
    __in  DWORD dwRop
);

hdc应该是什么?如何获取bmp?

花了一段时间,但我现在终于得到了一个正常运行的脚本。

要求:

#include <iostream>
#include <ole2.h>
#include <olectl.h>

此外,您可能(?)必须将ole32、oleout32和uuid添加到您的链接器中。

screenCapturePart:

bool screenCapturePart(int x, int y, int w, int h, LPCSTR fname){
    HDC hdcSource = GetDC(NULL);
    HDC hdcMemory = CreateCompatibleDC(hdcSource);
    int capX = GetDeviceCaps(hdcSource, HORZRES);
    int capY = GetDeviceCaps(hdcSource, VERTRES);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdcSource, w, h);
    HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap);
    BitBlt(hdcMemory, 0, 0, w, h, hdcSource, x, y, SRCCOPY);
    hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld);
    DeleteDC(hdcSource);
    DeleteDC(hdcMemory);
    HPALETTE hpal = NULL;
    if(saveBitmap(fname, hBitmap, hpal)) return true;
    return false;
}

保存位图:

bool saveBitmap(LPCSTR filename, HBITMAP bmp, HPALETTE pal)
{
    bool result = false;
    PICTDESC pd;
    pd.cbSizeofstruct   = sizeof(PICTDESC);
    pd.picType      = PICTYPE_BITMAP;
    pd.bmp.hbitmap  = bmp;
    pd.bmp.hpal     = pal;
    LPPICTURE picture;
    HRESULT res = OleCreatePictureIndirect(&pd, IID_IPicture, false,
                       reinterpret_cast<void**>(&picture));
    if (!SUCCEEDED(res))
    return false;
    LPSTREAM stream;
    res = CreateStreamOnHGlobal(0, true, &stream);
    if (!SUCCEEDED(res))
    {
    picture->Release();
    return false;
    }
    LONG bytes_streamed;
    res = picture->SaveAsFile(stream, true, &bytes_streamed);
    HANDLE file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, 0,
                 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if (!SUCCEEDED(res) || !file)
    {
    stream->Release();
    picture->Release();
    return false;
    }
    HGLOBAL mem = 0;
    GetHGlobalFromStream(stream, &mem);
    LPVOID data = GlobalLock(mem);
    DWORD bytes_written;
    result   = !!WriteFile(file, data, bytes_streamed, &bytes_written, 0);
    result  &= (bytes_written == static_cast<DWORD>(bytes_streamed));
    GlobalUnlock(mem);
    CloseHandle(file);
    stream->Release();
    picture->Release();
    return result;
}

您可以使用GetDC(NULL)获取整个屏幕的设备上下文,然后将其与BitBlt一起用作源设备上下文。

至于其他要做的事情:

位图创建(Windows)

位图存储(Windows)