/// <summary> /// Get only the points where issues were found /// If the captured image is smaller than the expected image, throw an exception and refuse to compare them. /// Otherwise, compare the expected image with the matching region (the upper left corner) of the rendered image. /// We'll do the comparison by x,y coordinates and not pointer math (ie: y*width +x) to ensure correct matching. /// </summary> /// <returns>Array of points where failures ocurred</returns> public static Point[] GetPointsWithFailures(Color[,] captured, RenderBuffer expected) { //we'll do the comparison by x,y coordinates and not pointer math (ie: y*width +x) to ensure correct matching. if (expected.Width > captured.GetLength(0) || expected.Height > captured.GetLength(1)) { throw new ApplicationException(exceptionCapturedRenderedEqual); } System.Collections.ArrayList failures = new System.Collections.ArrayList(); Point[] failPoints; for (int y = 0; y < expected.Height; y++) { for (int x = 0; x < expected.Width; x++) { if (!ColorOperations.AreWithinTolerance( captured[x, y], expected.FrameBuffer[x, y], expected.ToleranceBuffer[x, y])) { failures.Add(new Point(x, y)); } } } // Always return an array, even an empty one failPoints = new Point[failures.Count]; if (failures.Count != 0) { failures.CopyTo(failPoints); } return(failPoints); }
/// <summary> /// Produce a Difference image from a screen capture and a RenderBuffer. For every pixel, if it is an exact match or /// if the difference is within the provided tolerance, the pixel is marked as black. Otherwise the diff value is used. /// If the captured image is smaller than the expected image, throw an exception and refuse to compare them. /// Otherwise, compare the expected image with the matching region (the upper left corner) of the rendered image. /// We'll do the comparison by x,y coordinates and not pointer math (ie: y*width +x) to ensure correct matching. /// </summary> /// <returns>A new Render buffer with the Diff image on the framebuffer and a color coded image on the tbuffer.</returns> public static RenderBuffer ComputeDifference(Color[,] captured, RenderBuffer expected) { if (expected.Width > captured.GetLength(0) || expected.Height > captured.GetLength(1)) { throw new ApplicationException(exceptionCapturedRenderedEqual); } RenderBuffer result = new RenderBuffer(expected.Width, expected.Height); // We want to write to this directly, set z-test to always write ... result.DepthTestFunction = DepthTestFunction.Always; // We want to ignore any potential z-tolerance as well ... for (int y = 0; y < result.Height; y++) { for (int x = 0; x < result.Width; x++) { // Ignore alpha differences. Color diff = ColorOperations.AbsoluteDifference(expected.FrameBuffer[x, y], captured[x, y]); diff.A = 0xff; result.FrameBuffer[x, y] = diff; // Make perfect matches black if (ColorOperations.AreWithinTolerance(captured[x, y], expected.FrameBuffer[x, y], Colors.Black)) { result.ToleranceBuffer[x, y] = Colors.Black; result.FrameBuffer[x, y] = Colors.Black; } // Treat within tolerance as separate case else if (ColorOperations.AreWithinTolerance(captured[x, y], expected.FrameBuffer[x, y], expected.ToleranceBuffer[x, y])) { result.ToleranceBuffer[x, y] = codedColor[0]; result.FrameBuffer[x, y] = Colors.Black; } // Otherwise do color coding else { for (int i = 1; i < codedColor.Length; i++) { if (ColorOperations.AreWithinTolerance( captured[x, y], expected.FrameBuffer[x, y], ColorOperations.Add(toleranceThreshold[i], expected.ToleranceBuffer[x, y]))) { result.ToleranceBuffer[x, y] = codedColor[i]; break; } } } } } return(result); }