/// <summary> /// Perform a comparison between the generated image and the base one. /// </summary> /// <param name="receivedImage">The received image.</param> /// <returns>True if the tests were correctly performed.</returns> private bool CompareImage(TestResultServerImage receivedImage, string resultTempFileName) { var comparer = new ImageComparator { SaveJson = true }; return(comparer.Compare_RMSE(receivedImage, resultTempFileName)); }
private void ProcessSendImage(ImageComparerClient imageComparerClient, BinaryReader reader, BinaryWriter binaryWriter) { var receivedImage = new TestResultServerImage(imageComparerClient); // Read image header receivedImage.ClientImage.Read(reader); Console.WriteLine(@"Receiving {0} from {1}", receivedImage.ClientImage.TestName, imageComparerClient.Connection.Serial); // Compute paths var goldPath = Path.Combine(baseOutputPath, receivedImage.GetGoldDirectory()); var outputPath = Path.Combine(baseOutputPath, receivedImage.GetOutputDirectory()); receivedImage.GoldPath = goldPath; receivedImage.OutputPath = outputPath; receivedImage.JsonPath = Path.Combine(baseOutputPath, "json"); Directory.CreateDirectory(receivedImage.GoldPath); Directory.CreateDirectory(receivedImage.OutputPath); Directory.CreateDirectory(receivedImage.JsonPath); receivedImage.GoldFileName = Path.Combine(goldPath, receivedImage.GetFileName()); receivedImage.ResultFileName = Path.Combine(outputPath, receivedImage.GetFileName()); receivedImage.DiffFileName = Path.Combine(outputPath, receivedImage.GetDiffFileName()); receivedImage.DiffNormFileName = Path.Combine(outputPath, receivedImage.GetNormDiffFileName()); // Seems like image magick doesn't like to read from UNC path (size is OK but not data?) // Let's use temp path to do most of the work before copying var resultTempFileName = Path.GetTempPath() + Guid.NewGuid() + ".png"; try { // Read image data using (var image = receivedImage.ClientImage.Image) using (var resultFileStream = File.OpenWrite(resultTempFileName)) { image.Save(resultFileStream, ImageFileType.Png); } CompareImage(receivedImage, resultTempFileName); } finally { File.Delete(resultTempFileName); } var receivedImages = imageComparerClient.Images; List<TestResultServerImage> receivedImageForThisTest; lock (receivedImages) { if (!receivedImages.TryGetValue(receivedImage.ClientImage.TestName, out receivedImageForThisTest)) { receivedImageForThisTest = new List<TestResultServerImage>(); receivedImage.FrameIndex = receivedImageForThisTest.Count; receivedImages.Add(receivedImage.ClientImage.TestName, receivedImageForThisTest); } } receivedImageForThisTest.Add(receivedImage); // Send ack binaryWriter.Write(true); }
/// <summary> /// Perform a comparison between the generated image and the base one. /// </summary> /// <param name="receivedImage">The received image.</param> /// <returns>True if the tests were correctly performed.</returns> private bool CompareImage(TestResultServerImage receivedImage, string resultTempFileName) { var comparer = new ImageComparator { SaveJson = true }; return comparer.Compare_RMSE(receivedImage, resultTempFileName); }
private void ProcessSendImage(ImageComparerClient imageComparerClient, BinaryReader reader, BinaryWriter binaryWriter) { var receivedImage = new TestResultServerImage(imageComparerClient); // Read image header receivedImage.ClientImage.Read(reader); Console.WriteLine(@"Receiving {0} from {1}", receivedImage.ClientImage.TestName, imageComparerClient.Connection.Serial); // Compute paths var goldPath = Path.Combine(baseOutputPath, receivedImage.GetGoldDirectory()); var outputPath = Path.Combine(baseOutputPath, receivedImage.GetOutputDirectory()); receivedImage.GoldPath = goldPath; receivedImage.OutputPath = outputPath; receivedImage.JsonPath = Path.Combine(baseOutputPath, "json"); Directory.CreateDirectory(receivedImage.GoldPath); Directory.CreateDirectory(receivedImage.OutputPath); Directory.CreateDirectory(receivedImage.JsonPath); receivedImage.GoldFileName = Path.Combine(goldPath, receivedImage.GetFileName()); receivedImage.ResultFileName = Path.Combine(outputPath, receivedImage.GetFileName()); receivedImage.DiffFileName = Path.Combine(outputPath, receivedImage.GetDiffFileName()); receivedImage.DiffNormFileName = Path.Combine(outputPath, receivedImage.GetNormDiffFileName()); // Seems like image magick doesn't like to read from UNC path (size is OK but not data?) // Let's use temp path to do most of the work before copying var resultTempFileName = Path.GetTempPath() + Guid.NewGuid() + ".png"; try { // Read image data using (var image = receivedImage.ClientImage.Image) using (var resultFileStream = File.OpenWrite(resultTempFileName)) { image.Save(resultFileStream, ImageFileType.Png); } CompareImage(receivedImage, resultTempFileName); } finally { File.Delete(resultTempFileName); } var receivedImages = imageComparerClient.Images; List <TestResultServerImage> receivedImageForThisTest; lock (receivedImages) { if (!receivedImages.TryGetValue(receivedImage.ClientImage.TestName, out receivedImageForThisTest)) { receivedImageForThisTest = new List <TestResultServerImage>(); receivedImage.FrameIndex = receivedImageForThisTest.Count; receivedImages.Add(receivedImage.ClientImage.TestName, receivedImageForThisTest); } } receivedImageForThisTest.Add(receivedImage); // Send ack binaryWriter.Write(true); }
/// <summary> /// Performs the comparison between the generated image and its base. /// </summary> /// <param name="receivedImage">The received image.</param> /// <returns></returns> public bool Compare_RMSE(TestResultServerImage receivedImage, string resultTempFileName) { bool copyOnShare = (receivedImage.Client.Connection.Flags & ImageComparisonFlags.CopyOnShare) != 0; var testPerformed = false; // Test if gold file exists (if not, create it) if (!File.Exists(receivedImage.GoldFileName)) { Console.WriteLine(@"Generating a new gold image."); File.Delete(receivedImage.ResultFileName); // remove the old version of the result file, if it already exists. File.Copy(resultTempFileName, receivedImage.ResultFileName); File.Copy(resultTempFileName, receivedImage.GoldFileName); receivedImage.MeanSquareError = 0; // we don't want a error on request status after creating a new gold image } else { var tempGoldFileName = Path.GetTempPath() + Guid.NewGuid() + ".png"; var tempDiffFileName = Path.GetTempPath() + Guid.NewGuid() + ".png"; try { File.Copy(receivedImage.GoldFileName, tempGoldFileName); Console.WriteLine(@"Gold image found. Performing tests."); var output = RunImageMagickCommand( @"compare", string.Format( "-metric rmse \"{0}\" \"{1}\" \"{2}\"", tempGoldFileName, resultTempFileName, tempDiffFileName)); var outputResult = Regex.Match(output.OutputErrors[0], @"(\S*) \((\S*)\)"); var mse = 0.0f; if (!float.TryParse(outputResult.Groups[1].Value, out mse)) { var stringBuild = new StringBuilder(); stringBuild.Append("Errors:\n"); foreach (var err in output.OutputErrors) { stringBuild.Append(" "); stringBuild.Append(err); stringBuild.Append("\n"); } stringBuild.Append("Messages:\n"); foreach (var mess in output.OutputLines) { stringBuild.Append(" "); stringBuild.Append(mess); stringBuild.Append("\n"); } Console.WriteLine(@"Unable to read the value of the error between the two images."); Console.WriteLine(stringBuild.ToString()); } else { Console.WriteLine(@"Error: " + mse); //copy files to server if (mse != 0.0f) { Console.WriteLine(@"Existing difference with gold image. Continuing tests."); // visually compute difference RunImageMagickCommand( @"composite", string.Format( "\"{0}\" \"{1}\" -compose difference \"{2}\"", tempGoldFileName, resultTempFileName, tempDiffFileName)); // normalize the output RunImageMagickCommand( @"convert", string.Format( "\"{0}\" -auto-level \"{1}\"", tempDiffFileName, receivedImage.DiffNormFileName)); File.Copy(resultTempFileName, receivedImage.ResultFileName, true); File.Copy(tempDiffFileName, receivedImage.DiffFileName, true); } else { Console.WriteLine(@"No difference with gold image."); // Delete diff image (that might have been generated by previous run) File.Delete(receivedImage.DiffFileName); File.Delete(receivedImage.DiffNormFileName); } receivedImage.MeanSquareError = mse; if (SaveJson) WriteJson(receivedImage); testPerformed = true; } } catch (Exception ex) { Console.WriteLine(@"An exception occured in ImageMagick."); Console.WriteLine(ex); } finally { File.Delete(tempDiffFileName); File.Delete(tempGoldFileName); } } return testPerformed; }
/// <summary> /// Add the image to the json. /// </summary> /// <param name="receivedImage">The image to add.</param> /// <param name="baseImage">The address of the base image.</param> private void WriteJson(TestResultServerImage receivedImage) { lock (WriterLocker) { using (var stream = GetJsonFileStream(receivedImage)) { var newEntry = receivedImage.GetJsonString(); WriteInStream(newEntry, stream); WriteInStream("]", stream); } } }
/// <summary> /// Get the name of the json for this test. /// </summary> /// <param name="receivedImage">The received image information.</param> /// <returns>The name of the json file.</returns> private static string GetJsonFileName(TestResultServerImage receivedImage) { return Path.Combine(receivedImage.JsonPath, receivedImage.GetJsonFileName()); }
/// <summary> /// Get or Create the Json file for this build. /// </summary> /// <param name="receivedImage">The received image information.</param> /// <returns>The file stream.</returns> private Stream GetJsonFileStream(TestResultServerImage receivedImage) { var fileName = GetJsonFileName(receivedImage); bool fileExists = File.Exists(fileName); var stream = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Write); if (fileExists) { stream.Seek(-1, SeekOrigin.End); WriteInStream(",", stream); } else { WriteInStream("[", stream); } return stream; }