diff options
Diffstat (limited to 'Software/Experiments/Tango.RemoteDesktop/Tango.ScreenCapture/ImageComparer.cs')
| -rw-r--r-- | Software/Experiments/Tango.RemoteDesktop/Tango.ScreenCapture/ImageComparer.cs | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/Software/Experiments/Tango.RemoteDesktop/Tango.ScreenCapture/ImageComparer.cs b/Software/Experiments/Tango.RemoteDesktop/Tango.ScreenCapture/ImageComparer.cs new file mode 100644 index 000000000..fba20a00a --- /dev/null +++ b/Software/Experiments/Tango.RemoteDesktop/Tango.ScreenCapture/ImageComparer.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.ScreenCapture +{ + public class ImageComparer + { + unsafe public Bitmap CreateDifferenceBitmap(Bitmap previousImage, Bitmap currentImage, Color matchColor) + { + if (previousImage == null | currentImage == null) + throw new InvalidOperationException("Cannot compare image. They are the same instance"); + + if (previousImage.Height != currentImage.Height || previousImage.Width != currentImage.Width) + throw new InvalidOperationException("Cannot compare image of different size."); + + Bitmap diffImage = currentImage.Clone() as Bitmap; + + int height = previousImage.Height; + int width = previousImage.Width; + + BitmapData data1 = previousImage.LockBits(new Rectangle(0, 0, width, height), + ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); + BitmapData data2 = currentImage.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 - (previousImage.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 + } + } + + // at the end of each column, skip extra padding + if (rowPadding > 0) + { + data1Ptr += rowPadding; + data2Ptr += rowPadding; + diffPtr += rowPadding; + } + } + + previousImage.UnlockBits(data1); + currentImage.UnlockBits(data2); + diffImage.UnlockBits(diffData); + + return diffImage; + } + + unsafe public VectorDifferenceImage CreateDifferenceVector(Bitmap previousImage, Bitmap currentImage) + { + VectorDifferenceImage vector = new VectorDifferenceImage(previousImage.Width, previousImage.Height); + + if (previousImage == null | currentImage == null) + throw new InvalidOperationException("Cannot compare image. They are the same instance"); + + if (previousImage.Height != currentImage.Height || previousImage.Width != currentImage.Width) + throw new InvalidOperationException("Cannot compare image of different size."); + + int height = previousImage.Height; + int width = previousImage.Width; + + BitmapData data1 = previousImage.LockBits(new Rectangle(0, 0, width, height), + ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); + BitmapData data2 = currentImage.LockBits(new Rectangle(0, 0, width, height), + ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); + byte* data1Ptr = (byte*)data1.Scan0; + byte* data2Ptr = (byte*)data2.Scan0; + + int rowPadding = data1.Stride - (previousImage.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 + } + + if (same != 4) + { + vector.Pixels.Add(new VectorImagePixel() + { + X = (ushort)j, + Y = (ushort)i, + B = tmp[0], + G = tmp[1], + R = tmp[2], + }); + } + } + + // at the end of each column, skip extra padding + if (rowPadding > 0) + { + data1Ptr += rowPadding; + data2Ptr += rowPadding; + } + } + + previousImage.UnlockBits(data1); + currentImage.UnlockBits(data2); + + return vector; + } + } +} |
