/// <summary> /// Perform a synchronous comparison /// </summary> /// <param name="hwnd">The hwnd of the window to capture</param> /// <param name="rect">The area to capture within the hwnd </param> /// <returns>returns true on success, false on failure</returns> public bool Compare(IntPtr hwnd, System.Drawing.Rectangle rect) { using (AsyncData asyncData = CommonCompare(hwnd, rect, null)) { if (asyncData.MasterImage != null) { DoVscanCompare(asyncData); } return(asyncData.Result.Succeeded); } }
/// <summary> /// Perform an asynchronous image comparison /// </summary> /// <param name="hwnd">The hwnd of the window to capture</param> /// <param name="rect">The area to capture within the hwnd </param> public void EnqueueCompare(IntPtr hwnd, System.Drawing.Rectangle rect) { AsyncData asyncData = CommonCompare(hwnd, rect, new ManualResetEvent(false)); AsyncHelper.Data.Add(asyncData); if (asyncData.MasterImage != null) { ThreadPool.QueueUserWorkItem(DoVscanCompare, asyncData); } else { asyncData.SynchronizationObject.Set(); } }
private void DoVscanCompare(object asyncData) { AsyncData data = asyncData as AsyncData; if (data == null) { throw new ArgumentException("Parameter passed in to the Method not of type AsyncData (or null)", "asyncData"); } ImageComparator ic = new ImageComparator(); ic.Curve.CurveTolerance.LoadTolerance(data.ToleranceSettings.XmlNodeTolerance); IImageAdapter masterAdapter = new ImageAdapter(data.MasterImage); IImageAdapter capturedAdapter = new ImageAdapter(data.CapturedImage); // compare Master to the Capture image using the Compare overload that will scale the images size accounting for the DPI data.Result.Succeeded = ic.Compare(masterAdapter, MetadataInfoHelper.GetDpi(masterAdapter), capturedAdapter, MetadataInfoHelper.GetDpi(capturedAdapter), false); if (data.Result.Succeeded == false) { Microsoft.Test.Logging.GlobalLog.LogStatus("Regular comparison failed"); } // On filaure, check if user whats to filter the image ( IgnoreAntiAliasing will do ) IImageAdapter masterFiltered = null; IImageAdapter captureFiltered = null; if (data.Result.Succeeded == false && data.ToleranceSettings.Filter != null) { // first save error diff image string errorDiffName = ".\\ErrorDiff_" + data.Index + IMAGE_EXTENSION; ImageUtility.ToImageFile(ic.GetErrorDifference(ErrorDifferenceType.IgnoreAlpha), errorDiffName); Microsoft.Test.Logging.GlobalLog.LogFile(errorDiffName); // Compare failed, filter the images and retry Microsoft.Test.Logging.GlobalLog.LogStatus("Filtering and recompare"); masterFiltered = data.ToleranceSettings.Filter.Process(masterAdapter); captureFiltered = data.ToleranceSettings.Filter.Process(capturedAdapter); data.Result.Succeeded = ic.Compare(masterFiltered, captureFiltered, false); if (data.Result.Succeeded == false) { Microsoft.Test.Logging.GlobalLog.LogStatus("==> Filtered comparison failed as well"); } } if (data.Result.Succeeded) { Microsoft.Test.Logging.GlobalLog.LogStatus("Comparison SUCCEEDED."); } else { // Save Masters * filtered master for easy analysis string masterName = ".\\Master_" + data.Index + IMAGE_EXTENSION; data.MasterImage.Save(masterName, System.Drawing.Imaging.ImageFormat.Tiff); Microsoft.Test.Logging.GlobalLog.LogFile(masterName); if (masterFiltered != null) { string filteredMasterName = ".\\MasterFiltered_" + data.Index + IMAGE_EXTENSION; using (Bitmap filteredMaster = ImageUtility.ToBitmap(masterFiltered)) { SetMetadataToImage(filteredMaster); filteredMaster.Save(filteredMasterName, System.Drawing.Imaging.ImageFormat.Tiff); } Microsoft.Test.Logging.GlobalLog.LogFile(filteredMasterName); } // Save rendered image (as "Actual_n") for easy analysis string capturedName = ".\\Actual_" + data.Index + IMAGE_EXTENSION; data.CapturedImage.Save(capturedName, System.Drawing.Imaging.ImageFormat.Tiff); Microsoft.Test.Logging.GlobalLog.LogFile(capturedName); // Save actual filtered for easy analysis if (captureFiltered != null) { string filteredRenderedName = ".\\ActualFiltered_" + data.Index + IMAGE_EXTENSION; using (Bitmap filteredRendered = ImageUtility.ToBitmap(captureFiltered)) { SetMetadataToImage(filteredRendered); filteredRendered.Save(filteredRenderedName, System.Drawing.Imaging.ImageFormat.Tiff); } Microsoft.Test.Logging.GlobalLog.LogFile(filteredRenderedName); } // Master might need to be updated, save with correct name and metadata // // In this image, encode full criteria string name = System.IO.Path.GetFileName(data.MasterName); string originalName = name.Replace(IMAGE_EXTENSION, "_FullCtriteria" + IMAGE_EXTENSION); Microsoft.Test.Logging.GlobalLog.LogStatus("Saving master with all criteria (new master) as '" + originalName + "'"); SetMetadataToImage(data.CapturedImage); data.CapturedImage.Save(originalName, System.Drawing.Imaging.ImageFormat.Tiff); Microsoft.Test.Logging.GlobalLog.LogFile(originalName); // // In this image, encode only criteria that match the master string originalNameFull = name.Replace(IMAGE_EXTENSION, "_MatchingCriteria" + IMAGE_EXTENSION); Microsoft.Test.Logging.GlobalLog.LogStatus("Saving master with matching criteria encoded (to replace previous master) as '" + originalNameFull + "'"); MasterMetadata metadata = ImageMetadata.MetadataFromImage(data.MasterImage); // Keep master Criteria but update its Description. IMasterDimension[] keys = new IMasterDimension[metadata.Description.Count]; metadata.Description.Keys.CopyTo(keys, 0); for (int t = 0; t < keys.Length; t++) { metadata.Description[keys[t]] = keys[t].GetCurrentValue(); } ImageMetadata.SetMetadataToImage(metadata, data.CapturedImage); data.CapturedImage.Save(originalNameFull, System.Drawing.Imaging.ImageFormat.Tiff); Microsoft.Test.Logging.GlobalLog.LogFile(originalNameFull); // first save error diff image string errorDiffFilterName = ".\\ErrorDiffFiltered_" + data.Index + IMAGE_EXTENSION; if (data.ToleranceSettings.Filter == null) { // Not filter were applied, change name (so it's not confusing) errorDiffFilterName = ".\\ErrorDiff_" + data.Index + IMAGE_EXTENSION; } ImageUtility.ToImageFile(ic.GetErrorDifference(ErrorDifferenceType.IgnoreAlpha), errorDiffFilterName); Microsoft.Test.Logging.GlobalLog.LogFile(errorDiffFilterName); } data.Result.IsCompleted = true; if (data.SynchronizationObject != null) { data.SynchronizationObject.Set(); } }