private Bitmap GetDX11ScreenShot() { try { screenShot = null; screenShot = new Bitmap(WIDTH, HEIGHT, this.pixelFormat); if (dx11DuplicatedOutput != null) { dx11DuplicatedOutput.AcquireNextFrame(NEXT_FRAME_TIMEOUT, out dx11DuplFrameInfo, out dx11ScreenResource); dx11Device.ImmediateContext .CopyResource(dx11ScreenResource.QueryInterface <SharpDX.Direct3D11.Resource>(), dx11ScreenTexture); // cast from texture to surface, so we can access its bytes dx11ScreenSurface = dx11ScreenTexture.QueryInterface <SharpDX.DXGI.Surface>(); // map the resource to access it dx11Map = dx11ScreenSurface.Map(SharpDX.DXGI.MapFlags.Read); bmpData = screenShot.LockBits(boundsRect, ImageLockMode.WriteOnly, screenShot.PixelFormat); var sourcePtr = dx11Map.DataPointer; var destPtr = bmpData.Scan0; for (int y = 0; y < HEIGHT; y++) { // Copy a single line Utilities.CopyMemory(destPtr, sourcePtr, ARGB_WIDTH); // Advance pointers sourcePtr = IntPtr.Add(sourcePtr, dx11Map.Pitch); destPtr = IntPtr.Add(destPtr, bmpData.Stride); } dx11Device.ImmediateContext.UnmapSubresource(dx11ScreenTexture, 0); screenShot.UnlockBits(bmpData); dx11ScreenSurface.Unmap(); dx11ScreenSurface.Dispose(); dx11ScreenResource.Dispose(); dx11DuplicatedOutput.ReleaseFrame(); } else { return(screenShot = null); } dx11ScreenSurface = null; bmpData = null; GC.Collect(); return(screenShot); } catch (SharpDX.SharpDXException e) { if (e.ResultCode.Code == SharpDX.DXGI.ResultCode.WaitTimeout.Result.Code) { //screen does not changed LdpLog.Warning("DX11 surface timeout.. Recursion is coming:)"); return(GetDX11ScreenShot()); } else { return(screenShot = null); } } catch (Exception ex) { LdpLog.Error("GetDX11ScreenShot\n" + ex.Message); return(screenShot = null); } }
public Bitmap getScreenDX() { if (System.Windows.Forms.Screen.AllScreens[0].Bounds.Width != LEDSetup.SCREEN_W) { return(null); } try { SharpDX.DXGI.Resource screenResource; OutputDuplicateFrameInformation duplicateFrameInformation; // Try to get duplicated frame within given time duplicatedOutput.AcquireNextFrame(1000, out duplicateFrameInformation, out screenResource); // copy resource into memory that can be accessed by the CPU using (var screenTexture2D = screenResource.QueryInterface <Texture2D>()) device.ImmediateContext.CopyResource(screenTexture2D, screenTexture); // Get the desktop capture texture var mapSource = device.ImmediateContext.MapSubresource(screenTexture, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None); // Create Drawing.Bitmap var bitmap = new System.Drawing.Bitmap(LEDSetup.SCREEN_W, LEDSetup.SCREEN_H, PixelFormat.Format32bppArgb); var boundsRect = new System.Drawing.Rectangle(0, 0, LEDSetup.SCREEN_W, LEDSetup.SCREEN_H); // Copy pixels from screen capture Texture to GDI bitmap var mapDest = bitmap.LockBits(boundsRect, ImageLockMode.WriteOnly, bitmap.PixelFormat); var sourcePtr = mapSource.DataPointer; var destPtr = mapDest.Scan0; for (int y = 0; y < LEDSetup.SCREEN_H; y++) { // Copy a single line Utilities.CopyMemory(destPtr, sourcePtr, LEDSetup.SCREEN_W * 4); // Advance pointers sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch); destPtr = IntPtr.Add(destPtr, mapDest.Stride); } // Release source and dest locks bitmap.UnlockBits(mapDest); device.ImmediateContext.UnmapSubresource(screenTexture, 0); // Save the output //bitmap.Save(outputFileName, ImageFormat.Png); // Capture done screenResource.Dispose(); duplicatedOutput.ReleaseFrame(); invalid_calls = 0; return(bitmap); } catch (SharpDXException e) { if (e.ResultCode.Code != SharpDX.DXGI.ResultCode.WaitTimeout.Result.Code)// && e.ResultCode != SharpDX.DXGI.ResultCode.InvalidCall.Result.Code) { if (e.ResultCode.Code == SharpDX.DXGI.ResultCode.AccessLost.Result.Code) { Logger.QueueLine("Device access lost, reinitializing duplication"); setupDX(); System.Threading.Thread.Sleep(200); } else if (e.ResultCode.Code == SharpDX.DXGI.ResultCode.DeviceRemoved.Code) { Logger.QueueLine("Device removed, reinitializing duplication"); setupDX(); System.Threading.Thread.Sleep(200); } else if (e.ResultCode.Code == SharpDX.DXGI.ResultCode.InvalidCall.Code) { invalid_calls++; if (invalid_calls >= 10) { Logger.QueueLine("Too many invalid calls, reinitializing duplication"); setupDX(); } System.Threading.Thread.Sleep(200); } else { throw e; } } } catch (Exception e) { } return(null); }