using System.Drawing; using Vision.WindowCapture.GraphicsCapture.Helpers; using Windows.Foundation.Metadata; using Windows.Graphics.Capture; using Windows.Graphics.DirectX; using Windows.Win32.Foundation; namespace Vision.WindowCapture.GraphicsCapture; public class GraphicsCapture : IWindowCapture { private HWND _hWnd; private Direct3D11CaptureFramePool? _captureFramePool; private GraphicsCaptureItem? _captureItem; private GraphicsCaptureSession? _captureSession; public bool IsCapturing { get; private set; } public async Task StartAsync(HWND hWnd) { _hWnd = hWnd; /* // if use GraphicsCapturePicker, need to set this window handle // new WindowInteropHelper(this).Handle var picker = new GraphicsCapturePicker(); picker.SetWindow(hWnd); _captureItem = picker.PickSingleItemAsync().AsTask().Result; */ var device = Direct3D11Helper.CreateDevice(); _captureItem = CaptureHelper.CreateItemForWindow(_hWnd) ?? throw new InvalidOperationException("Failed to create capture item."); var size = _captureItem.Size; if (size.Width < 480 || size.Height < 360) { throw new InvalidOperationException("窗口画面大小小于480x360,无法使用"); } _captureItem.Closed += OnCaptureItemClosed; _captureFramePool = Direct3D11CaptureFramePool.Create(device, DirectXPixelFormat.B8G8R8A8UIntNormalized, 2, size); _captureSession = _captureFramePool.CreateCaptureSession(_captureItem); if (ApiInformation.IsWriteablePropertyPresent("Windows.Graphics.Capture.GraphicsCaptureSession", "IsBorderRequired")) { await GraphicsCaptureAccess.RequestAccessAsync(GraphicsCaptureAccessKind.Borderless); _captureSession.IsBorderRequired = false; _captureSession.IsCursorCaptureEnabled = false; } _captureSession.StartCapture(); IsCapturing = true; } /// /// How to handle window size changes? /// /// public Bitmap? Capture() { using var frame = _captureFramePool?.TryGetNextFrame(); return frame?.ToBitmap(); } public Task StopAsync() { _captureSession?.Dispose(); _captureFramePool?.Dispose(); _captureSession = default; _captureFramePool = default; _captureItem = default; _hWnd = HWND.Null; IsCapturing = false; return Task.CompletedTask; } private void OnCaptureItemClosed(GraphicsCaptureItem sender, object args) { StopAsync(); } }