C
C#3y ago
Vеrsette

Capturing images from specific DirectX window

I want to capture images (pretty quickly, so pretty much like a video) from different applications, and some of them are DirectX, so using things like GDI+ won't work. From reading a bit about it, I have found that I apparently can do it by using EasyHook and DLL injection, but hooking and DLL injection make me think about how would that work in videogames? Wouldn't an anticheat ban you for that? Windows.Graphics.Capture seems to work, but I couldn't find a way to get images from it.
17 Replies
ross
ross3y ago
Screen capture - UWP applications
The Windows.Graphics.Capture namespace provides APIs to acquire frames from a display or application window, to create video streams or snapshots to build collaborative and interactive experiences.
Vеrsette
VеrsetteOP3y ago
That's the one that I mentioned worked, but I couldn't find the way to get a single bitmap image from This seems like it should work, thanks, will look into it ^^ Edit: Dumb me thought that they are different things, it's apparently the same namespace and I just couldn't find any examples for doing what I wanted to. The example outputs a CanvasBitmap which is a thingie from the Win2D library, but it's possible to convert into anything else by saving it to a MemoryStream using CanvasBitmap.SaveAsync()
reflectronic
reflectronic3y ago
you do not even neccessarily need Win2D you could also use SoftwareBitmap.CreateCopyFromSurfaceAsync. if you need to save it as a PNG or something, you would then use BitmapEncoder i mean, it depends on what exactly you want to do with the picture unless you are actually writing a UWP application, it is a minor pain in the ass to actually use Win2D
Vеrsette
VеrsetteOP3y ago
What would I replace _canvasDevice CanvasDevice with in that case?
_framePool = Direct3D11CaptureFramePool.Create(
_canvasDevice, // D3D device
DirectXPixelFormat.B8G8R8A8UIntNormalized, // Pixel format
2, // Number of frames
_item.Size); // Size of the buffers
_framePool = Direct3D11CaptureFramePool.Create(
_canvasDevice, // D3D device
DirectXPixelFormat.B8G8R8A8UIntNormalized, // Pixel format
2, // Number of frames
_item.Size); // Size of the buffers
Also, is there any way to use this with .NET 6? If I set the target Windows version to the correct one in project settings, some using errors are fixed, but some are not, like IDirect3DDevice I fixed similar problems by adding the Microsoft.Windows.SDK.Contracts nuget package previously, but it doesn't seem to work in this case, as it probably somehow conflicts with me choosing the Windows target OS, and breaks the whole project
reflectronic
reflectronic3y ago
what error with IDirect3DDevice?
Vеrsette
VеrsetteOP3y ago
reflectronic
reflectronic3y ago
have you referenced Win2D?
Vеrsette
VеrsetteOP3y ago
Yes
reflectronic
reflectronic3y ago
which package did you reference exactly
Vеrsette
VеrsetteOP3y ago
Win2D.uwp 1.26.0
An easy-to-use Windows Runtime API for immediate mode 2D graphics rendering. For the Universal Windows Platform (Windows 10).
reflectronic
reflectronic3y ago
yes, that is why that package doesn't work with .NET 6 try using Microsoft.Graphics.Win2D instead it should work, and if it doesn't, you probably have to do that minor pain in the ass thing
Vеrsette
VеrsetteOP3y ago
Breaks stuff :/
Vеrsette
VеrsetteOP3y ago
By you probably have to do that minor pain in the ass thing you mean use SoftwareBitmap?
reflectronic
reflectronic3y ago
oh, um, yeah, Microsoft.Graphics.Win2D probably wouldn't work either you are going to have to create the device "manually"
Vеrsette
VеrsetteOP3y ago
Aaand, how do I do that? :>
reflectronic
reflectronic3y ago
my suggestion (untested): - add a reference to https://www.nuget.org/packages/Microsoft.Windows.CsWin32 - in your NativeMethods.txt (the readme explains), add: - CreateDirect3D11DeviceFromDXGIDevice - D3D11CreateDevice - D3D11_SDK_VERSION
unsafe
{
Marshal.ThrowExceptionForHR(Windows.Win32.PInvoke.D3D11CreateDevice(null,
Windows.Win32.Graphics.Direct3D.D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE,
null,
default,
default,
Windows.Win32.PInvoke.D3D11_SDK_VERSION,
out var device,
null,
out _));

Marshal.ThrowExceptionForHR(Windows.Win32.PInvoke.CreateDirect3D11DeviceFromDXGIDevice(
(Windows.Win32.Graphics.Dxgi.IDXGIDevice) device,
out var id3dDevice));

_device = MarshalGeneric<IDirect3DDevice>.FromAbi(Marshal.GetIUnknownForObject(id3dDevice));

GC.KeepAlive(id3dDevice);
}
unsafe
{
Marshal.ThrowExceptionForHR(Windows.Win32.PInvoke.D3D11CreateDevice(null,
Windows.Win32.Graphics.Direct3D.D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE,
null,
default,
default,
Windows.Win32.PInvoke.D3D11_SDK_VERSION,
out var device,
null,
out _));

Marshal.ThrowExceptionForHR(Windows.Win32.PInvoke.CreateDirect3D11DeviceFromDXGIDevice(
(Windows.Win32.Graphics.Dxgi.IDXGIDevice) device,
out var id3dDevice));

_device = MarshalGeneric<IDirect3DDevice>.FromAbi(Marshal.GetIUnknownForObject(id3dDevice));

GC.KeepAlive(id3dDevice);
}
Want results from more Discord servers?
Add your server