cuốn sách gpt4 ai đã làm

c++ - Chụp màn hình bằng DirectX

In lại Tác giả: Hồ Xil Thời gian cập nhật: 2023-11-01 14:56:48 hai mươi bốn 4
mua khóa gpt4 Nike

Tôi biết cách sử dụng GDI để chụp màn hình, nhưng nó rất chậm (chỉ chụp được 10 khung hình/giây)

Tôi đọc được rằng DirectX cung cấp tốc độ tốt nhất. Nhưng trước khi bắt đầu học DirectX, tôi muốn thử nghiệm một ví dụ để xem liệu nó có thực sự nhanh như vậy không.

Tôi tìm thấy cái nàyquestionMột mã mẫu được cung cấp để thực hiện việc này:

void dump_buffer()
{
IDirect3DSurface9* pRenderTarget=NULL;
IDirect3DSurface9* pDestTarget=NULL;
const char file[] = "Pickture.bmp";
// kiểm tra độ tỉnh táo.
nếu (Thiết bị == NULL)
return;

// lấy bề mặt mục tiêu kết xuất.
HRESULT giờ = Thiết bị->GetRenderTarget(0, &pRenderTarget);
// lấy chế độ hiển thị của bộ điều hợp hiện tại.
//hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode);

// tạo bề mặt đích.
hr = Thiết bị->CreateOffscreenPlainSurface(DisplayMde.Width,
DisplayMde.Height,
DisplayMde.Format,
D3DPOOL_HỆ THỐNG,
&pMục tiêu đích,
VÔ GIÁ TRỊ);
// sao chép mục tiêu kết xuất vào bề mặt đích.
hr = Thiết bị->GetRenderTargetData(pRenderTarget, pDestTarget);
// lưu nội dung của nó vào một tập tin bitmap.
hr = D3DXSaveSurfaceToFile(file,
D3DXIFF_BMP,
pDestTarget,
NULL,
VÔ GIÁ TRỊ);

// dọn dẹp.
pRenderTarget->Release();
pDestTarget->Release();
}

Tôi đã thử bao gồm các tập tin cần thiết. Tuy nhiên, không phải tất cả những thứ này đều có thể được bao gồm (ví dụ: #include ).

Bất cứ ai cũng có thể cung cấp một ví dụ hoạt động với tất cả các yêu cầu bao gồm hoặc chỉ ra những thư viện nào tôi nên cài đặt.

Tôi đang sử dụng Visual C++ 2010 Express trên Windows 7 Ultimate (x64).


biên tập:

Hơn nữa, mã này chưa hoàn chỉnh, ví dụ: Thiết bị Nó là gì? Định danh? !

câu trả lời hay nhất

Đây là một số mã mẫu để chụp màn hình bằng DirectX 9. Bạn không phải cài đặt bất kỳ SDK nào (ngoài SDK tiêu chuẩn đi kèm với Visual Studio, mặc dù tôi chưa thử nghiệm VS 2010).

Chỉ cần tạo một ứng dụng bảng điều khiển Win32 đơn giản và thêm nội dung sau vào tệp stdafx.h:

  #include  // chúng tôi sử dụng WIC để lưu hình ảnh
#include // Tiêu đề DirectX 9
#pragma comment(lib, "d3d9.lib") // liên kết tới thư viện DirectX 9

Đây là cách thực hiện chính của ví dụ

  int _tmain(int argc, _TCHAR* argv[])
{
HRESULT giờ = Direct3D9TakeScreenshots(D3DADAPTER_DEFAULT, 10);
return 0;
}

Điều này sẽ làm là chụp màn hình gấp 10 lần và lưu hình ảnh "cap%i.png" vào đĩa. Nó cũng sẽ hiển thị thời gian thực hiện việc này (việc lưu hình ảnh không được tính vào thời gian này, chỉ tính ảnh chụp màn hình). Trên máy của tôi (máy tính để bàn Windows 8 - Dell Precision M2800/i7-4810MQ-2.80GHz/Intel HD 4600, một máy thực sự tồi...) phải mất ~4 giây để chụp 100x1920x1080, tức là khoảng 20/25 khung hình/giây.

  HRESULT Direct3D9TakeScreenshots(bộ chuyển đổi UINT, số lượng UINT)
{
HRESULT giờ = S_OK;
IDirect3D9 *d3d = nullptr;
IDirect3DDevice9 *device = nullptr;
IDirect3DSurface9 *surface = nullptr;
Tham số D3DPRESENT_PARAMETERS = { 0 };
Chế độ D3DDISPLAYMODE;
D3DLOCKED_RECT RC;
cao độ UINT;
HỆ THỐNG THỜI GIAN;
LPBYTE *ảnh = nullptr;

// khởi tạo D3D và lấy kích thước màn hình
d3d = Direct3DCreate9(D3D_SDK_VERSION);
HRCHECK(d3d->GetAdapterDisplayMode(adapter, &mode));

tham số.Windowed = TRUE;
tham số.BackBufferCount = 1;
tham số.BackBufferHeight = mode.Height;
tham số.BackBufferWidth = mode.Width;
tham số.SwapEffect = D3DSWAPEFFECT_DISCARD;
tham số.hDeviceWindow = NULL;

// tạo thiết bị và chụp bề mặt
HRCHECK(d3d->CreateDevice(adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶meters, &device));
HRCHECK(thiết bị->CreateOffscreenPlainSurface(mode.Width, mode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, nullptr));

// tính kích thước bộ đệm cần thiết
HRCHECK(surface->LockRect(&rc, NULL, 0));
cao độ = rc.Pitch;
HRCHECK(bề mặt->UnlockRect());

// phân bổ bộ đệm ảnh chụp màn hình
số lần chụp = LPBYTE mới[đếm];
cho (UINT i = 0; i < đếm; i++)
{
shot[i] = new BYTE[pitch * mode.Height];
}

GetSystemTime(&st); // đo thời gian chúng ta dành cho việc chụp
wprintf(L"%i:%i:%i.%i\n", st.wHour, st.wMinute, st.wSecond, st.wMilli giây);
cho (UINT i = 0; i < đếm; i++)
{
// lấy dữ liệu
HRCHECK(thiết bị->GetFrontBufferData(0, bề mặt));

// sao chép nó vào bộ đệm của chúng tôi
HRCHECK(surface->LockRect(&rc, NULL, 0));
CopyMemory(shots[i], rc.pBits, rc.Pitch * mode.Height);
HRCHECK(bề mặt->UnlockRect());
}
GetSystemTime(&st);
wprintf(L"%i:%i:%i.%i\n", st.wHour, st.wMinute, st.wSecond, st.wMilli giây);

// lưu tất cả ảnh chụp màn hình
cho (UINT i = 0; i < đếm; i++)
{
Tệp WCHAR [100];
wsprintf(file, L"cap%i.png", i);
HRCHECK(SavePixelsToFile32bppPBGRA(mode.Width, mode.Height, pitch, shot[i], file, GUID_ContainerFormatPng));
}

dọn dẹp:
nếu (ảnh != nullptr)
{
cho (UINT i = 0; i < đếm; i++)
{
xóa ảnh[i];
}
xóa[] ảnh;
}
PHÁT HÀNH(bề mặt);
PHÁT HÀNH(thiết bị);
PHÁT HÀNH(d3d);
trở về giờ;
}

Xin lưu ý rằng mã này được liên kết ngầm với WIC (một thư viện hình ảnh có trong Windows đã có sẵn được một thời gian) lưu các tệp hình ảnh (vì vậy bạn không cần D3DXSaveSurfaceToFile nổi tiếng yêu cầu cài đặt DirectX SDK cũ):

  HRESULT SavePixelsToFile32bppPBGRA(UINT chiều rộng, UINT chiều cao, UINT bước, LPBYTE pixel, LPWSTR đường dẫn tệp, const GUID &định dạng)
{
if (!filePath || !pixel)
trả về E_INVALIDARG;

HRESULT giờ = S_OK;
IWICImagingFactory *factory = nullptr;
IWICBitmapEncoding *bộ mã hóa = nullptr;
IWICBitmapFrameEncode *frame = nullptr;
IWICStream *stream = nullptr;
GUID pf = GUID_WICPixelFormat32bppPBGRA;
BOOL coInit = CoInitialize(nullptr);

HRCHECK(CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory)));
HRCHECK(nhà máy->CreateStream(&stream));
HRCHECK(stream->InitializeFromFilename(filePath, GENERIC_WRITE));
HRCHECK(nhà máy->CreateEncode(định dạng, nullptr, &bộ mã hóa));
HRCHECK(bộ mã hóa->Khởi tạo(luồng, WICBitmapEncodingNoCache));
HRCHECK(encode->CreateNewFrame(&frame, nullptr)); // chúng tôi không sử dụng tùy chọn ở đây
HRCHECK(frame->Initialize(nullptr)); // chúng tôi không sử dụng bất kỳ tùy chọn nào ở đây
HRCHECK(khung->SetSize(chiều rộng, chiều cao));
HRCHECK(frame->SetPixelFormat(&pf));
HRCHECK(frame->WritePixels(chiều cao, sải chân, sải chân * chiều cao, pixel));
HRCHECK(frame->Commit());
HRCHECK(bộ mã hóa->Cam kết());

dọn dẹp:
PHÁT HÀNH(luồng);
PHÁT HÀNH(khung);
PHÁT HÀNH(bộ mã hóa);
PHÁT HÀNH (nhà máy);
if (coInit) CoUninitialize();
trở về giờ;
}

Và một số macro tôi sử dụng:

  #define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)
#define HRCHECK(__expr) {hr=(__expr);if(FAILED(hr)){wprintf(L"FAILURE 0x%08X (%i)\n\tline: %u file: '%s'\n\texpr : '" WIDEN(#__expr) L"'\n",hr, hr, __LINE__,__WFILE__);goto dọn dẹp;}}
#define RELEASE(__p) {if(__p!=nullptr){__p->Release();__p=nullptr;}}

LƯU Ý: Đối với máy khách Windows 8+, tất cả những thứ này (ngoại trừ WIC) phải bị xóa để hỗ trợ API sao chép máy tính để bàn .

LƯU Ý: Đối với người dùng .NET, có phiên bản C#:trực tiếpN

Về c++ - Chụp màn hình bằng DirectX, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/30021274/

hai mươi bốn 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress