Esempio n. 1
0
        /// <summary>
        /// Compares two images based on defined set up.
        /// </summary>
        /// <returns>An instance of <see cref="ComparisonResult"/> that results of comparison.</returns>
        public ComparisonResult Compare()
        {
            if (_baselineImage == null)
            {
                throw new ArgumentNullException(nameof(_baselineImage), "Baseline image is required. Use CompareTo(...) method.");
            }

            if (_scaleToSameSize)
            {
                _actualImage = _resizer.Resize(_actualImage, _baselineImage.Width, _baselineImage.Height);
            }

            var comparisonAreaWidth = _actualImage.Width > _baselineImage.Width
                ? _actualImage.Width
                : _baselineImage.Width;

            var comparisonAreaHeight = _actualImage.Height > _baselineImage.Height
                ? _actualImage.Height
                : _baselineImage.Height;

            var comparisonResultImage = new Bitmap(comparisonAreaWidth, comparisonAreaHeight);

            var pixelMismatchCount = 0;

            var differenceBounds = new DifferenceBounds
            {
                Top    = comparisonAreaHeight,
                Left   = comparisonAreaWidth,
                Bottom = 0,
                Right  = 0
            };

            void updateBounds(int x, int y)
            {
                differenceBounds.Left   = Math.Min(x, differenceBounds.Left);
                differenceBounds.Right  = Math.Max(x, differenceBounds.Right);
                differenceBounds.Top    = Math.Min(y, differenceBounds.Top);
                differenceBounds.Bottom = Math.Max(y, differenceBounds.Bottom);
            }

            var startTime = DateTime.Now;

            var skipTheRest = false;

            for (var horizontalPosition = 0; horizontalPosition < comparisonAreaWidth; horizontalPosition++)
            {
                for (var verticalPosition = 0; verticalPosition < comparisonAreaHeight; verticalPosition++)
                {
                    if (skipTheRest ||
                        !IsPixelInBounds(_actualImage, horizontalPosition, verticalPosition) ||
                        !IsPixelInBounds(_baselineImage, horizontalPosition, verticalPosition))
                    {
                        break;
                    }

                    var actualPixel   = _actualImage.GetPixel(horizontalPosition, verticalPosition);
                    var expectedPixel = _baselineImage.GetPixel(horizontalPosition, verticalPosition);

                    var errorPixel = GetColorOfDifference(_settings.DifferenceType.Value)(actualPixel, expectedPixel);

                    var isPixelComparable = IsPixelComparable(expectedPixel, horizontalPosition, verticalPosition);

                    if (_ignoreColors)
                    {
                        if (IsPixelBrightnessSimilar(actualPixel, expectedPixel) || !isPixelComparable)
                        {
                            if (!_compareOnly && _settings.DifferenceType != DifferenceType.DiffOnly)
                            {
                                SetGrayScaledPixel(comparisonResultImage, expectedPixel, horizontalPosition, verticalPosition);
                            }
                        }
                        else
                        {
                            if (!_compareOnly)
                            {
                                comparisonResultImage.SetPixel(horizontalPosition, verticalPosition, errorPixel);
                            }

                            pixelMismatchCount++;
                            updateBounds(horizontalPosition, verticalPosition);
                        }
                        continue;
                    }

                    if (IsRGBSimilar(actualPixel, expectedPixel) || !isPixelComparable)
                    {
                        if (!_compareOnly && _settings.DifferenceType != DifferenceType.DiffOnly)
                        {
                            SetTransparentPixel(comparisonResultImage, actualPixel, horizontalPosition, verticalPosition);
                        }
                    }
                    else if (
                        _ignoreAntialiasing &&
                        (IsAntialiased(_actualImage, horizontalPosition, verticalPosition) ||
                         IsAntialiased(_baselineImage, horizontalPosition, verticalPosition))
                        )
                    {
                        if (IsPixelBrightnessSimilar(actualPixel, expectedPixel) || !isPixelComparable)
                        {
                            if (!_compareOnly && _settings.DifferenceType != DifferenceType.DiffOnly)
                            {
                                SetGrayScaledPixel(comparisonResultImage, expectedPixel, horizontalPosition, verticalPosition);
                            }
                        }
                        else
                        {
                            if (!_compareOnly)
                            {
                                comparisonResultImage.SetPixel(horizontalPosition, verticalPosition, errorPixel);
                            }

                            pixelMismatchCount++;
                            updateBounds(horizontalPosition, verticalPosition);
                        }
                    }
                    else
                    {
                        if (!_compareOnly)
                        {
                            comparisonResultImage.SetPixel(horizontalPosition, verticalPosition, errorPixel);
                        }

                        pixelMismatchCount++;
                        updateBounds(horizontalPosition, verticalPosition);
                    }

                    if (_compareOnly)
                    {
                        var currentMisMatchPercent = (double)pixelMismatchCount / (comparisonAreaHeight * comparisonAreaWidth) * 100;

                        if (currentMisMatchPercent > _returnEarlyThreshold)
                        {
                            skipTheRest = true;
                        }
                    }
                }
            }

            var rawMisMatchPercentage = (float)pixelMismatchCount / (comparisonAreaHeight * comparisonAreaWidth) * 100;

            return(new ComparisonResult
            {
                DiffBounds = differenceBounds,
                Mismatch = rawMisMatchPercentage,
                AnalysisTime = DateTime.Now - startTime,

                ImageDifference = !_compareOnly
                    ? ImageOperations.ConvertToBase64(comparisonResultImage)
                    : null,

                IsSameDimensions =
                    _actualImage.Width == _baselineImage.Width &&
                    _actualImage.Height == _baselineImage.Height,

                DimensionDifference = new DimensionDifference
                {
                    Width = _actualImage.Width - _baselineImage.Width,
                    Height = _actualImage.Height - _baselineImage.Height
                }
            });
        }