예제 #1
0
        private Color GetTolerance(Point point, Color expected)
        {
            // pixelCenter is factored into this point

            int x = (int)Math.Floor(point.X - Const.pixelCenterX);
            int y = (int)Math.Floor(point.Y - Const.pixelCenterY);

            Color missingPixelTolerance = ColorOperations.ColorFromArgb(0, 0, 0, 0);
            Color lookupTolerance       = ColorOperations.ColorFromArgb(0, 0, 0, 0);

            for (int j = y; j < y + 2; j++)
            {
                for (int i = x; i < x + 2; i++)
                {
                    Color?current = SafeGetPixel(i, j);
                    if (current.HasValue)
                    {
                        // Keep the max of the diff tolerance and the existing tolerance
                        Color diff = ColorOperations.AbsoluteDifference(current.Value, expected);
                        lookupTolerance = ColorOperations.Max(lookupTolerance, diff);
                        lookupTolerance = ColorOperations.Max(lookupTolerance, toleranceBuffer[i, j]);
                    }
                    else
                    {
                        // increase tolerance by 25% since this pixel's value is unknown
                        missingPixelTolerance = ColorOperations.Add(missingPixelTolerance, ColorOperations.ColorFromArgb(.25, .25, .25, .25));
                    }
                }
            }
            return(ColorOperations.Add(lookupTolerance, missingPixelTolerance));
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <summary/>
        virtual public Color FilteredErrorLookup(Point uvLow, Point uvHigh, Color computedColor)
        {
            // Mipmapping uses a recursive texture pyramid where each level is 1/4 of the previous one.
            // This makes it necessary to maintain a 1:1 width:height sample ratio for
            // error tolerance estimation since that is the area that the mipmapped sample was computed from.
            double uvWidth  = uvHigh.X - uvLow.X;
            double uvHeight = uvHigh.Y - uvLow.Y;

            // Force 1:1 aspect ratio on the larger side
            if (uvWidth > uvHeight)
            {
                double vFix = (uvWidth - uvHeight) / 2.0;
                uvLow.Y  -= vFix;
                uvHigh.Y += vFix;
            }
            else
            {
                double uFix = (uvHeight - uvWidth) / 2.0;
                uvLow.X  -= uFix;
                uvHigh.X += uFix;
            }

            // Define where we want to have texel centers
            double texelCenterX = 0.5;
            double texelCenterY = 0.5;
            // -/+ texelCenters so that we always at least compare against the raw indices of bilinear filtering
            int xLo = (int)Math.Floor(uvLow.X * width - (1 - texelCenterX));
            int xHi = (int)Math.Ceiling(uvHigh.X * width + texelCenterX);
            int yLo = (int)Math.Floor(uvLow.Y * height - (1 - texelCenterY));
            int yHi = (int)Math.Ceiling(uvHigh.Y * height + texelCenterY);

            Color tolerance = Color.FromArgb(0x00, 0x00, 0x00, 0x00);

            for (int y = yLo; y <= yHi; y++)
            {
                for (int x = xLo; x <= xHi; x++)
                {
                    Color current = GetColor(x, y);
                    Color diff    = ColorOperations.AbsoluteDifference(current, computedColor);
                    tolerance = ColorOperations.Max(tolerance, diff);
                }
            }

            return(tolerance);
        }