/// <summary> /// Read back the data from the texture into a CPU buffer /// </summary> /// <param name="buffer"></param> public void ReadBack(byte[] buffer) { Stopwatch Timer = new Stopwatch(); Timer.Start(); try { FDevice.StretchRectangle(this.FTextureShared.GetSurfaceLevel(0), this.FTextureCopied.GetSurfaceLevel(0), TextureFilter.None); FDevice.GetRenderTargetData(this.FTextureCopied.GetSurfaceLevel(0), FSurfaceOffscreen); var rect = FSurfaceOffscreen.LockRectangle(LockFlags.ReadOnly); try { rect.Data.Read(buffer, 0, buffer.Length); FSurfaceOffscreen.UnlockRectangle(); } catch (Exception e) { FSurfaceOffscreen.UnlockRectangle(); throw; } } catch (Exception e) { FDevice.EndScene(); throw; } Timer.Stop(); Debug.Print(Timer.Elapsed.TotalMilliseconds.ToString()); }
/// <summary> /// Gets the specified region (identified in client coordinates) from the current surface /// </summary> /// <param name="region">The region (in client coordinates, e.g. <see cref="NativeMethods.GetClientRect"/> is the entire window content).</param> /// <returns>A new Bitmap object (must be Disposed by caller)</returns> public Bitmap GetSurfaceRegion(Rectangle region) { if (_captureHwnd == IntPtr.Zero) { return(null); } #region Create a copy of the surface image NativeMethods.UpdateWindowShared(_captureHwnd, 0, 0, 0, IntPtr.Zero, IntPtr.Zero); Surface.FromSurface(_renderTarget, _sharedSurface, Filter.None, 0); _deviceEx.GetRenderTargetData(_renderTarget, _systemMemorySurface); #endregion #region Put the data into a Bitmap // Note: during my tests I found that the captured area includes space for the window chrome // but filled in black. // Take into consideration the window chrome Size chrome = NativeMethods.GetWindowChromeSize(_captureHwnd); region.X += chrome.Width; region.Y += chrome.Height; // We need to convert Width and Height to x2, and y2 respectively, because // Surface.ToStream(...) expects the rectangle to have x1,y1,x2,y2 not x1,y1,width,height // (SlimDX version 2.0.6.40) region.Width += region.X; region.Height += region.Y; DataStream stream = Surface.ToStream(_systemMemorySurface, ImageFileFormat.Bmp, region); Bitmap surfaceBitmap = (Bitmap)Image.FromStream(stream); stream.Close(); stream.Dispose(); #endregion return(surfaceBitmap); }