7
7
namespace Codeuctivity . ImageSharpCompare
8
8
{
9
9
/// <summary>
10
- /// ImageSharpCompare, compares images. Use this class to compare images using a third image as mask of regions where your two compared images may differ. An alpha channel is ignored.
10
+ /// ImageSharpCompare, compares images.
11
+ /// Use this class to compare images using a third image as mask of regions where your two compared images may differ.
12
+ /// An alpha channel is ignored.
11
13
/// </summary>
12
14
#pragma warning disable CA1724 // Type names should not match namespaces - this is accepted for now to prevent a breaking change
13
15
@@ -529,6 +531,22 @@ public static Image CalcDiffMaskImage(string pathActualImage, string pathExpecte
529
531
return CalcDiffMaskImage ( actual , expected , resizeOption ) ;
530
532
}
531
533
534
+ /// <summary>
535
+ /// Creates a diff mask image of two images
536
+ /// </summary>
537
+ /// <param name="pathActualImage"></param>
538
+ /// <param name="pathExpectedImage"></param>
539
+ /// <param name="pathMaskImage"></param>
540
+ /// <param name="resizeOption"></param>
541
+ /// <returns>Image representing diff, black means no diff between actual image and expected image, white means max diff</returns>
542
+ public static Image CalcDiffMaskImage ( string pathActualImage , string pathExpectedImage , string pathMaskImage , ResizeOption resizeOption = ResizeOption . DontResize )
543
+ {
544
+ using var actual = Image . Load ( pathActualImage ) ;
545
+ using var expected = Image . Load ( pathExpectedImage ) ;
546
+ using var mask = Image . Load ( pathMaskImage ) ;
547
+ return CalcDiffMaskImage ( actual , expected , mask , resizeOption ) ;
548
+ }
549
+
532
550
/// <summary>
533
551
/// Creates a diff mask image of two images
534
552
/// </summary>
@@ -543,6 +561,22 @@ public static Image CalcDiffMaskImage(Stream actualImage, Stream expectedImage,
543
561
return CalcDiffMaskImage ( actual , expected , resizeOption ) ;
544
562
}
545
563
564
+ /// <summary>
565
+ /// Creates a diff mask image of two images
566
+ /// </summary>
567
+ /// <param name="actualImage"></param>
568
+ /// <param name="expectedImage"></param>
569
+ /// <param name="maskImage"></param>
570
+ /// <param name="resizeOption"></param>
571
+ /// <returns>Image representing diff, black means no diff between actual image and expected image, white means max diff</returns>
572
+ public static Image CalcDiffMaskImage ( Stream actualImage , Stream expectedImage , Stream maskImage , ResizeOption resizeOption = ResizeOption . DontResize )
573
+ {
574
+ using var actual = Image . Load ( actualImage ) ;
575
+ using var expected = Image . Load ( expectedImage ) ;
576
+ using var mask = Image . Load ( maskImage ) ;
577
+ return CalcDiffMaskImage ( actual , expected , mask , resizeOption ) ;
578
+ }
579
+
546
580
/// <summary>
547
581
/// Creates a diff mask image of two images
548
582
/// </summary>
@@ -587,6 +621,48 @@ public static Image CalcDiffMaskImage(Image actual, Image expected, ResizeOption
587
621
}
588
622
}
589
623
624
+ /// <summary>
625
+ /// Creates a diff mask image of two images
626
+ /// </summary>
627
+ /// <param name="actual"></param>
628
+ /// <param name="expected"></param>
629
+ /// <param name="mask"></param>
630
+ /// <param name="resizeOption"></param>
631
+ /// <returns>Image representing diff, black means no diff between actual image and expected image, white means max diff</returns>
632
+ public static Image CalcDiffMaskImage ( Image actual , Image expected , Image mask , ResizeOption resizeOption = ResizeOption . DontResize )
633
+ {
634
+ var ownsActual = false ;
635
+ var ownsExpected = false ;
636
+ var ownsMask = false ;
637
+ Image < Rgb24 > ? actualRgb24 = null ;
638
+ Image < Rgb24 > ? expectedRgb24 = null ;
639
+ Image < Rgb24 > ? maskRgb24 = null ;
640
+
641
+ try
642
+ {
643
+ actualRgb24 = ToRgb24Image ( actual , out ownsActual ) ;
644
+ expectedRgb24 = ToRgb24Image ( expected , out ownsExpected ) ;
645
+ maskRgb24 = ToRgb24Image ( mask , out ownsMask ) ;
646
+
647
+ return CalcDiffMaskImage ( actualRgb24 , expectedRgb24 , maskRgb24 , resizeOption ) ;
648
+ }
649
+ finally
650
+ {
651
+ if ( ownsActual )
652
+ {
653
+ actualRgb24 ? . Dispose ( ) ;
654
+ }
655
+ if ( ownsExpected )
656
+ {
657
+ expectedRgb24 ? . Dispose ( ) ;
658
+ }
659
+ if ( ownsMask )
660
+ {
661
+ maskRgb24 ? . Dispose ( ) ;
662
+ }
663
+ }
664
+ }
665
+
590
666
/// <summary>
591
667
/// Creates a diff mask image of two images
592
668
/// </summary>
@@ -639,6 +715,60 @@ public static Image CalcDiffMaskImage(Image<Rgb24> actual, Image<Rgb24> expected
639
715
}
640
716
}
641
717
718
+ /// <summary>
719
+ /// Creates a diff mask image of two images using a image mask for tolerated difference between the two images.
720
+ /// </summary>
721
+ /// <param name="actual"></param>
722
+ /// <param name="expected"></param>
723
+ /// <param name="mask"></param>
724
+ /// <param name="resizeOption"></param>
725
+ /// <returns>Image representing diff, black means no diff between actual image and expected image, white means max diff</returns>
726
+ public static Image CalcDiffMaskImage ( Image < Rgb24 > actual , Image < Rgb24 > expected , Image < Rgb24 > mask , ResizeOption resizeOption = ResizeOption . DontResize )
727
+ {
728
+ var imagesHaveSameDimensions = ImagesHaveSameDimension ( actual , expected ) && ImagesHaveSameDimension ( actual , mask ) ;
729
+
730
+ if ( ! imagesHaveSameDimensions && resizeOption == ResizeOption . DontResize )
731
+ {
732
+ throw new ImageSharpCompareException ( sizeDiffersExceptionMessage ) ;
733
+ }
734
+
735
+ if ( imagesHaveSameDimensions )
736
+ {
737
+ var maskImageResult = new Image < Rgb24 > ( actual . Width , actual . Height ) ;
738
+
739
+ for ( var x = 0 ; x < actual . Width ; x ++ )
740
+ {
741
+ for ( var y = 0 ; y < actual . Height ; y ++ )
742
+ {
743
+ var maskPixel = mask [ x , y ] ;
744
+ var actualPixel = actual [ x , y ] ;
745
+ var expectedPixel = expected [ x , y ] ;
746
+
747
+ maskImageResult [ x , y ] = new Rgb24
748
+ {
749
+ R = ( byte ) Math . Max ( byte . MinValue , Math . Abs ( expectedPixel . R - actualPixel . R ) - maskPixel . R ) ,
750
+ G = ( byte ) Math . Max ( byte . MinValue , Math . Abs ( expectedPixel . G - actualPixel . G ) - maskPixel . G ) ,
751
+ B = ( byte ) Math . Max ( byte . MinValue , Math . Abs ( expectedPixel . B - actualPixel . B ) - maskPixel . B )
752
+ } ;
753
+ }
754
+ }
755
+
756
+ return maskImageResult ;
757
+ }
758
+
759
+ var grown = GrowToSameDimension ( actual , expected , mask ) ;
760
+ try
761
+ {
762
+ return CalcDiffMaskImage ( grown . Item1 , grown . Item2 , grown . Item3 , ResizeOption . DontResize ) ;
763
+ }
764
+ finally
765
+ {
766
+ grown . Item1 ? . Dispose ( ) ;
767
+ grown . Item2 ? . Dispose ( ) ;
768
+ grown . Item3 ? . Dispose ( ) ;
769
+ }
770
+ }
771
+
642
772
private static Image < Rgb24 > ToRgb24Image ( Image actual , out bool ownsImage )
643
773
{
644
774
if ( actual is Image < Rgb24 > actualPixelAccessibleImage )
0 commit comments