diff --git a/Program.cs b/Program.cs index 015db5b..d12402b 100644 --- a/Program.cs +++ b/Program.cs @@ -420,7 +420,7 @@ static CelebrityAnalysisResult AnalyzeImageForCelebrities(Bitmap sourceImage) } } - static PriceRange GetPriceRange(string caption, double confidence, float expensiveMultiplier) + static PriceRange GetPriceRange(string caption, double confidence, float expensiveMultiplier, Random rnd) { PriceRange priceRange; priceRange.lowPrice = 0; @@ -433,7 +433,6 @@ static PriceRange GetPriceRange(string caption, double confidence, float expensi } // Randomly increase price - Random rnd = new Random(); priceRange.highPrice *= (int)(1.0f + rnd.NextDouble() * 3.0); priceRange.highPrice = (int)(priceRange.highPrice * expensiveMultiplier); @@ -505,7 +504,8 @@ static Appraisal CreateAppraisal(Bitmap sourceImage, AnalysisBlob analysisResult bool isSign = SignDetection.IsSign(analysisResult); Console.WriteLine("Is Sign: " + isSign); - Bitmap composedImage = ComposeImage(sourceImage, descriptionText, confidence, isOld, isBlackAndWhite && isPhoto, expensiveMultiplier, isPainting, isSign); + Random random = new Random(); + Bitmap composedImage = ComposeImage(sourceImage, descriptionText, confidence, isOld, isBlackAndWhite && isPhoto, expensiveMultiplier, isPainting, isSign, random); //string comment = Comment.Get(); @@ -694,7 +694,7 @@ static string GetForegroundColor(AnalysisResult analysisResult) return color; } - public static Bitmap ComposeImage(Bitmap sourceImage, string descriptionText, float confidence, bool isOld, bool isBlackAndWhitePhoto, float expensiveMultiplier, bool isPainting, bool isSign) + public static Bitmap ComposeImage(Bitmap sourceImage, string descriptionText, float confidence, bool isOld, bool isBlackAndWhitePhoto, float expensiveMultiplier, bool isPainting, bool isSign, Random random) { Bitmap drawnBitmap = null; @@ -707,7 +707,7 @@ public static Bitmap ComposeImage(Bitmap sourceImage, string descriptionText, fl drawnBitmap = sourceImage.Clone(); } - PriceRange priceRange = GetPriceRange(descriptionText, confidence, expensiveMultiplier); + PriceRange priceRange = GetPriceRange(descriptionText, confidence, expensiveMultiplier, random); int year = GetYear(drawnBitmap, isOld, isBlackAndWhitePhoto); string fullCaption = descriptionText + String.Format(" (ca. {0})\n ${1:0,0}-${2:0,0}", year, priceRange.lowPrice, priceRange.highPrice); diff --git a/test/TestComposeImage.cs b/test/TestComposeImage.cs index 65eeef4..57624af 100644 --- a/test/TestComposeImage.cs +++ b/test/TestComposeImage.cs @@ -3,6 +3,7 @@ using System.Reflection; using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Advanced; using Xunit; using PixelColor = SixLabors.ImageSharp.PixelFormats.Rgba32; @@ -21,7 +22,7 @@ public static void UpdateExpectedOutput() public static Bitmap ComposeImage() { - Bitmap sourceImage = Program.LoadImage(Program.LoadImageType.Test, "sourceImage0.jpg"); + Bitmap sourceImage = Program.LoadImage(Program.LoadImageType.Test, "sourceImage0.jpg"); return Program.ComposeImage( sourceImage, @@ -31,17 +32,71 @@ public static Bitmap ComposeImage() false, 1.0f, false, - false); + false, + GetDeterministicRandom()); } - } + public static Random GetDeterministicRandom() + { + return new Random(0); + } + + public static bool AreImagesTheSame(Bitmap imageA, Bitmap imageB) + { + float percentDifference = GetPercentDifference(imageA, imageB); + return percentDifference >= 0.0f && percentDifference <= 0.001f; + } + + public static float GetPercentDifference(Bitmap imageA, Bitmap imageB) + { + if (imageA.Height != imageB.Height || imageA.Width != imageB.Width) + { + return 100.0f; + } + + float totalPixels = imageA.Height * imageA.Width; + float amountOfPixelDifference = 0.0f; + + for (int y = 0; y < imageA.Height; y++) + { + Span aSpan = imageA.GetPixelRowSpan(y); + Span bSpan = imageB.GetPixelRowSpan(y); + + for (int x = 0; x < imageA.Width; x++) + { + PixelColor aPixel = aSpan[x]; + PixelColor bPixel = bSpan[x]; + + int pixelDistance = GetManhattanDistanceInRgbaSpace(ref aPixel, ref bPixel); + + float pixelDifference = pixelDistance / ( 256.0f * 4.0f ); + + amountOfPixelDifference += pixelDifference; + } + } + + return amountOfPixelDifference / totalPixels; + } + + private static int GetManhattanDistanceInRgbaSpace(ref PixelColor a, ref PixelColor b) + { + return Diff(a.R, b.R) + Diff(a.G, b.G) + Diff(a.B, b.B) + Diff(a.A, b.A); + } + + private static int Diff(ushort a, ushort b) => Math.Abs(a - b); + } + public static class TestComposeImage { - [Fact] public static void ComposeImageAcceptanceTest() { - TestComposeImageUtils.ComposeImage(); + Bitmap actualImage = TestComposeImageUtils.ComposeImage(); + + Bitmap expectedImage = Program.LoadImage(Program.LoadImageType.Test, "finalImage0.jpg"); + + Assert.True(TestComposeImageUtils.AreImagesTheSame(actualImage, expectedImage)); } } -} \ No newline at end of file +} +