diff options
Diffstat (limited to 'Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs')
| -rw-r--r-- | Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs b/Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs new file mode 100644 index 000000000..34250cc59 --- /dev/null +++ b/Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.RemoteDesktop.Frames; + +namespace Tango.RemoteDesktop.Comparers +{ + /// <summary> + /// Represents a raster <see cref="IBitmapComparer{TFrame}"/> comparer which will compare and return a <see cref="RasterFrame"/> difference. + /// </summary> + /// <seealso cref="Tango.RemoteDesktop.IBitmapComparer{Tango.RemoteDesktop.Frames.RasterFrame}" /> + public class RasterBitmapComparer : IBitmapComparer<RasterFrame> + { + /// <summary> + /// Creates the difference as <see cref="RasterFrame"/>. + /// </summary> + /// <param name="previousBitmap">The previous bitmap.</param> + /// <param name="currentBitmap">The current bitmap.</param> + /// <returns></returns> + /// <exception cref="InvalidOperationException"> + /// Cannot compare image. They are the same instance + /// or + /// Cannot compare image of different size. + /// </exception> + unsafe public BitmapComparerResult<RasterFrame> CreateDifference(Bitmap previousBitmap, Bitmap currentBitmap) + { + if (previousBitmap == null | currentBitmap == null) + throw new InvalidOperationException("Cannot compare image. They are the same instance"); + + if (previousBitmap.Height != currentBitmap.Height || previousBitmap.Width != currentBitmap.Width) + throw new InvalidOperationException("Cannot compare image of different size."); + + bool hasDifference = false; + + Color matchColor = Color.Transparent; + + Bitmap diffImage = currentBitmap.Clone() as Bitmap; + + int height = previousBitmap.Height; + int width = previousBitmap.Width; + + BitmapData data1 = previousBitmap.LockBits(new Rectangle(0, 0, width, height), + ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); + BitmapData data2 = currentBitmap.LockBits(new Rectangle(0, 0, width, height), + ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); + BitmapData diffData = diffImage.LockBits(new Rectangle(0, 0, width, height), + ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); + + byte* data1Ptr = (byte*)data1.Scan0; + byte* data2Ptr = (byte*)data2.Scan0; + byte* diffPtr = (byte*)diffData.Scan0; + + byte[] swapColor = new byte[4]; + swapColor[0] = matchColor.B; + swapColor[1] = matchColor.G; + swapColor[2] = matchColor.R; + swapColor[3] = matchColor.A; + + int rowPadding = data1.Stride - (previousBitmap.Width * 4); + + // iterate over height (rows) + for (int i = 0; i < height; i++) + { + // iterate over width (columns) + for (int j = 0; j < width; j++) + { + int same = 0; + + byte[] tmp = new byte[4]; + + // compare pixels and copy new values into temporary array + for (int x = 0; x < 4; x++) + { + tmp[x] = data2Ptr[0]; + if (data1Ptr[0] == data2Ptr[0]) + { + same++; + } + data1Ptr++; // advance image1 ptr + data2Ptr++; // advance image2 ptr + } + + // swap color or add new values + for (int x = 0; x < 4; x++) + { + diffPtr[0] = (same == 4) ? swapColor[x] : tmp[x]; + diffPtr++; // advance diff image ptr + } + + if (same != 4) + { + hasDifference = true; + } + } + + // at the end of each column, skip extra padding + if (rowPadding > 0) + { + data1Ptr += rowPadding; + data2Ptr += rowPadding; + diffPtr += rowPadding; + } + } + + previousBitmap.UnlockBits(data1); + currentBitmap.UnlockBits(data2); + diffImage.UnlockBits(diffData); + + return new BitmapComparerResult<RasterFrame>() + { + Frame = new RasterFrame(diffImage), + ContainsDifference = hasDifference + }; + } + } +} |
