using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; using Tango.RemoteDesktop; using Tango.RemoteDesktop.CaptureMethods; using Tango.RemoteDesktop.Encoders; using Tango.RemoteDesktop.Engines; using Tango.RemoteDesktop.Frames; namespace WpfApp1 { /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { private RasterScreenCaptureEngine _engine; private Bitmap _currentBitmap; public MainWindow() { InitializeComponent(); ContentRendered += MainWindow_ContentRendered; _engine = new RasterScreenCaptureEngine() { CaptureRegion = new CaptureRegion(0, 0, 1280, 800) }; _engine.CaptureMethod = new GdiScreenCapture(); _engine.FrameRate = 5; //Per second _engine.CaptureCursor = true; _engine.FrameReceived += _engine_FrameReceived; } private void _engine_FrameReceived(object sender, ScreenCaptureFrameReceivedEventArgs e) { BitmapSource preview = null; Stopwatch watch = new Stopwatch(); int size = 0; long encodingTime = 0; if (e.Frame.DifferenceAvailable) { if (e.Frame.DifferenceCount > 0) { watch.Restart(); var diffFrame = e.Frame.ToDifference(); MemoryStream bitmapStream = null; //This is the best possible outcome !!! diffFrame = diffFrame.OptimizeBounds(); bitmapStream = diffFrame.ToEncoder().ToStream(); encodingTime = watch.ElapsedMilliseconds; size = (int)bitmapStream.Length; Bitmap newBitmap = new Bitmap(bitmapStream); diffFrame = new RasterFrame(newBitmap, diffFrame.Left, diffFrame.Top); diffFrame.Apply(_currentBitmap); diffFrame.Dispose(); bitmapStream.Dispose(); var updatedFrame = new RasterFrame(_currentBitmap); preview = updatedFrame.ToBitmapSource(); Debug.WriteLine($"Actual frame size on network: {Math.Round((double)size / 1000d, 2)} kb, Encoding time: {encodingTime} milli, Differences: {e.Frame.DifferenceCount}"); Dispatcher.BeginInvoke(new Action(() => { img.Source = preview; })); } else { //No need to send new frames (no differences)... } } else { _currentBitmap = e.Frame.ToBitmap().Clone() as Bitmap; preview = e.Frame.ToBitmapSource(); size = e.Frame.ToEncoder().ToArray().Length; Dispatcher.BeginInvoke(new Action(() => { img.Source = preview; })); } e.Frame.Dispose(); } private void MainWindow_ContentRendered(object sender, EventArgs e) { _engine.Start(); } } }