private void ProcessFrame(DesktopFrame frame) { // Get the desktop capture texture var mapSource = _mDevice.ImmediateContext.MapSubresource(_desktopImageTexture, 0, MapMode.Read, MapFlags.None); var bounds = (Rectangle)_mOutputDesc.DesktopBounds; FinalImage = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb); var boundsRect = new global::System.Drawing.Rectangle(0, 0, bounds.Width, bounds.Height); // Copy pixels from screen capture Texture to GDI bitmap var mapDest = FinalImage.LockBits(boundsRect, ImageLockMode.WriteOnly, FinalImage.PixelFormat); var sourcePtr = mapSource.DataPointer; var destPtr = mapDest.Scan0; for (var y = 0; y < bounds.Height; y++) { // Copy a single line Utilities.CopyMemory(destPtr, sourcePtr, bounds.Width * 4); // Advance pointers sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch); destPtr = IntPtr.Add(destPtr, mapDest.Stride); } // Release source and dest locks FinalImage.UnlockBits(mapDest); _mDevice.ImmediateContext.UnmapSubresource(_desktopImageTexture, 0); frame.DesktopImage = (Bitmap)FinalImage.Clone(); }
private void RetrieveFrameMetadata(DesktopFrame frame) { if (_frameInfo.TotalMetadataBufferSize > 0) { // Get moved regions var movedRegionsLength = 0; var movedRectangles = new OutputDuplicateMoveRectangle[_frameInfo.TotalMetadataBufferSize]; _mDeskDupl.GetFrameMoveRects(movedRectangles.Length, movedRectangles, out movedRegionsLength); frame.MovedRegions = new MovedRegion[movedRegionsLength / Marshal.SizeOf(typeof(OutputDuplicateMoveRectangle))]; for (var i = 0; i < frame.MovedRegions.Length; i++) { var destRect = (Rectangle)movedRectangles[i].DestinationRect; frame.MovedRegions[i] = new MovedRegion { Source = new Point(movedRectangles[i].SourcePoint.X, movedRectangles[i].SourcePoint.Y), Destination = new global::System.Drawing.Rectangle(destRect.X, destRect.Y, destRect.Width, destRect.Height) }; } // Get dirty regions var dirtyRegionsLength = 0; var dirtyRectangles = new RawRectangle[_frameInfo.TotalMetadataBufferSize]; _mDeskDupl.GetFrameDirtyRects(dirtyRectangles.Length, dirtyRectangles, out dirtyRegionsLength); frame.UpdatedRegions = new global::System.Drawing.Rectangle[dirtyRegionsLength / Marshal.SizeOf(typeof(Rectangle))]; frame.FinishedRegions = new FinishedRegions[frame.UpdatedRegions.Length]; for (var i = 0; i < frame.UpdatedRegions.Length; i++) { var dirtyRect = (Rectangle)dirtyRectangles[i]; var rect = new global::System.Drawing.Rectangle(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height); frame.FinishedRegions[i] = new FinishedRegions { Destination = rect, Frame = ExtractRect(rect.X, rect.Y, rect.Width, rect.Height) }; } } else { frame.MovedRegions = new MovedRegion[0]; frame.UpdatedRegions = new global::System.Drawing.Rectangle[0]; } }
private Bitmap ExtractRect(int originX, int originY, int width, int height) { // Get the desktop capture screenTexture var mapSource = _mDevice.ImmediateContext.MapSubresource(_desktopImageTexture, 0, MapMode.Read, MapFlags.None); // Create Drawing.Bitmap var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); //不能是ARGB var boundsRect = new global::System.Drawing.Rectangle(0, 0, width, height); // 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; sourcePtr = IntPtr.Add(sourcePtr, originY * mapSource.RowPitch + originX * 4); for (var y = 0; y < height; y++) { // Copy a single line Utilities.CopyMemory(destPtr, sourcePtr, width * 4); // Advance pointers if (y != height - 1) { sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch); } destPtr = IntPtr.Add(destPtr, mapDest.Stride); } // Release source and dest locks bitmap.UnlockBits(mapDest); _mDevice.ImmediateContext.UnmapSubresource(_desktopImageTexture, 0); return(bitmap); }