Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/cla.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
path-to-document: 'https://github.com/Codeuctivity/SkiaSharp.Compare/blob/main/cla.md' # e.g. a CLA or a DCO document
# branch should not be protected
branch: 'cla'
allowlist: dependabot[bot],stesee,github-actions[bot],github-copilot[bot],copilot[bot]
allowlist: dependabot[bot],stesee,github-actions[bot],github-copilot[bot],copilot[bot],copilot-swe-agent[bot]

#below are the optional inputs - If the optional inputs are not given, then default values will be taken
#remote-organization-name: enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository)
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ env:

on:
push:
paths-ignore:
- '**.md'

jobs:
build:
Expand Down
36 changes: 31 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ NOTE: The Alpha-channel is ignored.
bool isEqual = Compare.ImagesAreEqual("actual.png", "expected.png");
```

### Calculates diff
### [Calculates diff](https://dotnetfiddle.net/tTnq2j)

```csharp
var calcDiff = Compare.CalcDiff("2x2PixelBlack.png", "2x2PixelWhite.png");
Console.WriteLine($"PixelErrorCount: {diff.PixelErrorCount}");
Console.WriteLine($"PixelErrorPercentage: {diff.PixelErrorPercentage}");
Console.WriteLine($"AbsoluteError: {diff.AbsoluteError}");
Console.WriteLine($"MeanError: {diff.MeanError}");
Console.WriteLine($"PixelErrorCount: {calcDiff.PixelErrorCount}");
Console.WriteLine($"PixelErrorPercentage: {calcDiff.PixelErrorPercentage}");
Console.WriteLine($"AbsoluteError: {calcDiff.AbsoluteError}");
Console.WriteLine($"MeanError: {calcDiff.MeanError}");
// PixelErrorCount: 4
// PixelErrorPercentage: 100
// AbsoluteError: 3060
Expand Down Expand Up @@ -65,3 +65,29 @@ Example - Compare two images using the created difference image. Add white pixel
var maskedDiff = SkiaSharpCompare.CalcDiff(pathPic1, pathPic2, "differenceMask.png");
Assert.That(maskedDiff.AbsoluteError, Is.EqualTo(0));
```

### [Configure transparency, enable metadata compare, ...](https://dotnetfiddle.net/lygaRU)

```csharp
var comparer = new ImageCompare(ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel, pixelColorShiftTolerance: 5, compareMetadata: true);
var calcDiff = comparer.CalcDiff("pngPartialTransparent4x4Pixel.png", "2x2PixelWhite.png");
// Displaying the differences
Console.WriteLine($"PixelErrorCount: {calcDiff.PixelErrorCount}");
Console.WriteLine($"PixelErrorPercentage: {calcDiff.PixelErrorPercentage}");
Console.WriteLine($"AbsoluteError: {calcDiff.AbsoluteError}");
Console.WriteLine($"MeanError: {calcDiff.MeanError}");
foreach (var metadataDifference in calcDiff.MetadataDifferences)
Console.WriteLine($"Metadata Difference: {metadataDifference}");

// PixelErrorCount: 16
// PixelErrorPercentage: 100
// AbsoluteError: 14272
// MeanError: 892
// Metadata Difference: [File:File Name, (pngPartialTransparent4x4Pixel.png, 2x2PixelWhite.png)]
// Metadata Difference: [File:File Size, (688 bytes, 556 bytes)]
// Metadata Difference: [PNG-IHDR:Color Type, (True Color with Alpha, True Color)]
// Metadata Difference: [PNG-IHDR:Image Height, (4, 2)]
// Metadata Difference: [PNG-IHDR:Image Width, (4, 2)]
// Metadata Difference: [PNG-tEXt:Textual Data, (Software: Paint.NET 5.1.2, Comment: Created with GIMP)]
// ...
```
37 changes: 29 additions & 8 deletions SkiaSharpCompare/docs/nugetReadme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,42 @@
bool isEqual = Compare.ImagesAreEqual("actual.png", "expected.png");
```

## Calculates diff
## [Calculates diff](https://dotnetfiddle.net/tTnq2j)

```csharp
var calcDiff = Compare.CalcDiff("2x2PixelBlack.png", "2x2PixelWhite.png");
Console.WriteLine($"PixelErrorCount: {diff.PixelErrorCount}");
Console.WriteLine($"PixelErrorPercentage: {diff.PixelErrorPercentage}");
Console.WriteLine($"AbsoluteError: {diff.AbsoluteError}");
Console.WriteLine($"MeanError: {diff.MeanError}");
Console.WriteLine($"PixelErrorCount: {calcDiff.PixelErrorCount}");
Console.WriteLine($"PixelErrorPercentage: {calcDiff.PixelErrorPercentage}");
Console.WriteLine($"AbsoluteError: {calcDiff.AbsoluteError}");
Console.WriteLine($"MeanError: {calcDiff.MeanError}");
// PixelErrorCount: 4
// PixelErrorPercentage: 100
// AbsoluteError: 3060
// MeanError: 765
```

## Further features
## [Configure transparency, enable metadata compare, ...](https://dotnetfiddle.net/lygaRU)

- Diff mask: allowing defined areas to diff from the compared image.
- Compare images that have different dimension
```csharp
var comparer = new ImageCompare(ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel, pixelColorShiftTolerance: 5, compareMetadata: true);
var calcDiff = comparer.CalcDiff("pngPartialTransparent4x4Pixel.png", "2x2PixelWhite.png");
// Displaying the differences
Console.WriteLine($"PixelErrorCount: {calcDiff.PixelErrorCount}");
Console.WriteLine($"PixelErrorPercentage: {calcDiff.PixelErrorPercentage}");
Console.WriteLine($"AbsoluteError: {calcDiff.AbsoluteError}");
Console.WriteLine($"MeanError: {calcDiff.MeanError}");
foreach (var metadataDifference in calcDiff.MetadataDifferences)
Console.WriteLine($"Metadata Difference: {metadataDifference}");

// PixelErrorCount: 16
// PixelErrorPercentage: 100
// AbsoluteError: 14272
// MeanError: 892
// Metadata Difference: [File:File Name, (pngPartialTransparent4x4Pixel.png, 2x2PixelWhite.png)]
// Metadata Difference: [File:File Size, (688 bytes, 556 bytes)]
// Metadata Difference: [PNG-IHDR:Color Type, (True Color with Alpha, True Color)]
// Metadata Difference: [PNG-IHDR:Image Height, (4, 2)]
// Metadata Difference: [PNG-IHDR:Image Width, (4, 2)]
// Metadata Difference: [PNG-tEXt:Textual Data, (Software: Paint.NET 5.1.2, Comment: Created with GIMP)]
// ...
```
30 changes: 15 additions & 15 deletions SkiaSharpCompareTestNunit/SkiaSharpCompareTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void ShouldVerifyThatImageStreamsSizeAreEqual(string pathActual, string p
[TestCase(TestFiles.png0Rgba32, TestFiles.png0Rgba32, ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.jpg0Rgb24, TestFiles.jpg0Rgb24, ResizeOption.DontResize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.png0Rgba32, TestFiles.png0Rgba32, ResizeOption.DontResize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.pngTransparent2x2px, TestFiles.pngPartialTransparent2x2px, ResizeOption.DontResize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.pngTransparent4x4px, TestFiles.pngPartialTransparent4x4px, ResizeOption.DontResize, TransparencyOptions.IgnoreAlphaChannel)]
public void ShouldVerifyThatImagesAreEqual(string pathActual, string pathExpected, ResizeOption resizeOption, TransparencyOptions transparencyOptions)
{
var sut = new ImageCompare(resizeOption, transparencyOptions);
Expand Down Expand Up @@ -131,8 +131,8 @@ public void ShouldVerifyThatSkiaSharpImagesAreEqual(string pathActual, string pa
[TestCase(TestFiles.renderedForm2, TestFiles.renderedForm1, 49267623, 60.794204096742348d, 174178, 21.49284304047384d, ResizeOption.Resize, 0, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.colorShift1, TestFiles.colorShift2, 117896, 3.437201166180758d, 30398, 88.623906705539355d, ResizeOption.DontResize, 0, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.colorShift1, TestFiles.colorShift2, 0, 0, 0, 0, ResizeOption.DontResize, 15, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.pngPartialTransparent2x2px, TestFiles.pngTransparent2x2px, 2048, 128.0d, 16, 100, ResizeOption.DontResize, 0, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.pngPartialTransparent2x2px, TestFiles.pngTransparent2x2px, 0, 0, 0, 0, ResizeOption.DontResize, 0, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.pngPartialTransparent4x4px, TestFiles.pngTransparent4x4px, 2048, 128.0d, 16, 100, ResizeOption.DontResize, 0, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.pngPartialTransparent4x4px, TestFiles.pngTransparent4x4px, 0, 0, 0, 0, ResizeOption.DontResize, 0, TransparencyOptions.IgnoreAlphaChannel)]
public void ShouldVerifyThatImagesAreSemiEqual(string pathPic1, string pathPic2, int expectedAbsoluteError, double expectedMeanError, int expectedPixelErrorCount, double expectedPixelErrorPercentage, ResizeOption resizeOption, int colorShiftTolerance, TransparencyOptions transparencyOptions)
{
var sut = new ImageCompare(resizeOption, transparencyOptions, colorShiftTolerance);
Expand Down Expand Up @@ -212,7 +212,7 @@ public void ShouldCalcDiffMaskSKBitmap(string pathPic1, string pathPic2, int exp

[TestCase(TestFiles.png0Rgba32, TestFiles.png1Rgba32, null, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.pngWhite2x2px, TestFiles.pngBlack2x2px, ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.pngTransparent2x2px, TestFiles.pngPartialTransparent2x2px, ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.pngTransparent4x4px, TestFiles.pngPartialTransparent4x4px, ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.png0Rgba32, TestFiles.png1Rgba32, ResizeOption.DontResize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.png0Rgba32, TestFiles.png1Rgba32, ResizeOption.Resize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.pngWhite2x2px, TestFiles.pngBlack4x4px, ResizeOption.Resize, TransparencyOptions.IgnoreAlphaChannel)]
Expand Down Expand Up @@ -259,15 +259,15 @@ private static void SaveAsPng(SKBitmap maskImage, FileStream fileStreamDifferenc
[TestCase(TestFiles.jpg0Rgb24, TestFiles.jpg1Rgb24, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.pngBlack2x2px, TestFiles.pngBlack4x4px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.pngBlack2x2px, TestFiles.pngWhite2x2px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.pngTransparent2x2px, TestFiles.pngWhite2x2px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.pngTransparent2x2px, TestFiles.pngBlack4x4px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.pngTransparent4x4px, TestFiles.pngWhite2x2px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.pngTransparent4x4px, TestFiles.pngBlack4x4px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.CompareAlphaChannel)]
[TestCase(TestFiles.png0Rgba32, TestFiles.png1Rgba32, 0, 0, 0, 0, ResizeOption.DontResize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.jpg0Rgb24, TestFiles.jpg1Rgb24, 0, 0, 0, 0, ResizeOption.DontResize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.jpg0Rgb24, TestFiles.jpg1Rgb24, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.pngBlack2x2px, TestFiles.pngBlack4x4px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.pngBlack2x2px, TestFiles.pngWhite2x2px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.pngTransparent2x2px, TestFiles.pngWhite2x2px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.pngTransparent2x2px, TestFiles.pngBlack4x4px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.pngTransparent4x4px, TestFiles.pngWhite2x2px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.IgnoreAlphaChannel)]
[TestCase(TestFiles.pngTransparent4x4px, TestFiles.pngBlack4x4px, 0, 0, 0, 0, ResizeOption.Resize, TransparencyOptions.IgnoreAlphaChannel)]
public void ShouldCalcDiffMaskSKBitmapAndUseOutcome(string pathPic1, string pathPic2, int expectedMeanError, int expectedAbsoluteError, int expectedPixelErrorCount, double expectedPixelErrorPercentage, ResizeOption resizeOption, TransparencyOptions transparencyOptions)
{
var sut = new ImageCompare(resizeOption, transparencyOptions);
Expand All @@ -294,7 +294,7 @@ public void ShouldCalcDiffMaskSKBitmapAndUseOutcome(string pathPic1, string path
Assert.That(maskedDiff.PixelErrorPercentage, Is.EqualTo(expectedPixelErrorPercentage), "PixelErrorPercentage");
}

[TestCase(TestFiles.pngWhite2x2px, TestFiles.pngBlack2x2px, TestFiles.pngTransparent2x2px, 765, 12240, 16, 100d, ResizeOption.Resize, 0)]
[TestCase(TestFiles.pngWhite2x2px, TestFiles.pngBlack2x2px, TestFiles.pngTransparent4x4px, 765, 12240, 16, 100d, ResizeOption.Resize, 0)]
[TestCase(TestFiles.pngWhite2x2px, TestFiles.pngBlack2x2px, TestFiles.pngBlack4x4px, 765, 12240, 16, 100d, ResizeOption.Resize, 0)]
[TestCase(TestFiles.pngBlack2x2px, TestFiles.pngBlack2x2px, TestFiles.pngBlack4x4px, 0, 0, 0, 0, ResizeOption.Resize, 0)]
[TestCase(TestFiles.pngBlack2x2px, TestFiles.pngBlack4x4px, TestFiles.pngBlack2x2px, 0, 0, 0, 0, ResizeOption.Resize, 0)]
Expand Down Expand Up @@ -363,8 +363,8 @@ public void CalcDiffStreams(string pathPic1, string pathPic2, int expectedMeanEr
[TestCase(TestFiles.colorShift1, TestFiles.colorShift2, TransparencyOptions.CompareAlphaChannel, 20)]
[TestCase(TestFiles.png0Rgba32, TestFiles.png1Rgba32, TransparencyOptions.IgnoreAlphaChannel, 0)]
[TestCase(TestFiles.colorShift1, TestFiles.colorShift2, TransparencyOptions.IgnoreAlphaChannel, 20)]
[TestCase(TestFiles.pngTransparent2x2px, TestFiles.pngPartialTransparent2x2px, TransparencyOptions.IgnoreAlphaChannel, 0)]
[TestCase(TestFiles.pngTransparent2x2px, TestFiles.pngPartialTransparent2x2px, TransparencyOptions.CompareAlphaChannel, 0)]
[TestCase(TestFiles.pngTransparent4x4px, TestFiles.pngPartialTransparent4x4px, TransparencyOptions.IgnoreAlphaChannel, 0)]
[TestCase(TestFiles.pngTransparent4x4px, TestFiles.pngPartialTransparent4x4px, TransparencyOptions.CompareAlphaChannel, 0)]
public void CalcDiffMaskImage_WhenSupplyingDiffMaskOfTwoImagesByFilePath_NoDifferences(string image1RelativePath, string image2RelativePath, TransparencyOptions transparencyOptions, int colorShiftTolerance)
{
var sut = new ImageCompare(ResizeOption.DontResize, transparencyOptions, colorShiftTolerance);
Expand Down Expand Up @@ -443,7 +443,7 @@ public void CalcDiffMaskImage_WhenSupplyingDiffMaskOfTwoImagesByImage_NoDifferen
[TestCase(TestFiles.jpg0Rgb24, TestFiles.png0Rgba32)]
[TestCase(TestFiles.jpg1Rgb24, TestFiles.png1Rgba32)]
[TestCase(TestFiles.colorShift1, TestFiles.colorShift2)]
[TestCase(TestFiles.pngTransparent2x2px, TestFiles.pngPartialTransparent2x2px)]
[TestCase(TestFiles.pngTransparent4x4px, TestFiles.pngPartialTransparent4x4px)]
public void ShouldVerifyThatImagesAreNotEqual(string pathActual, string pathExpected)
{
var sut = new ImageCompare();
Expand All @@ -460,7 +460,7 @@ public void ShouldVerifyThatImagesAreNotEqual(string pathActual, string pathExpe
[TestCase(TestFiles.jpg0Rgb24, TestFiles.png0Rgba32)]
[TestCase(TestFiles.jpg1Rgb24, TestFiles.png1Rgba32)]
[TestCase(TestFiles.colorShift1, TestFiles.colorShift2)]
[TestCase(TestFiles.pngTransparent2x2px, TestFiles.pngPartialTransparent2x2px)]
[TestCase(TestFiles.pngTransparent4x4px, TestFiles.pngPartialTransparent4x4px)]
public void ShouldVerifyThatImageStreamAreNotEqual(string pathActual, string pathExpected)
{
var sut = new ImageCompare();
Expand Down Expand Up @@ -489,8 +489,8 @@ public void ShouldVerifyThatImageWithDifferentSizeThrows(string pathPic1, string
[TestCase(TestFiles.png0Rgba32, TestFiles.png0Rgba32, TestFiles.pngBlack2x2px)]
[TestCase(TestFiles.png0Rgba32, TestFiles.pngBlack2x2px, TestFiles.png0Rgba32)]
[TestCase(TestFiles.pngBlack2x2px, TestFiles.png0Rgba32, TestFiles.png0Rgba32)]
[TestCase(TestFiles.pngPartialTransparent2x2px, TestFiles.png0Rgba32, TestFiles.png0Rgba32)]
[TestCase(TestFiles.png0Rgba32, TestFiles.png0Rgba32, TestFiles.pngPartialTransparent2x2px)]
[TestCase(TestFiles.pngPartialTransparent4x4px, TestFiles.png0Rgba32, TestFiles.png0Rgba32)]
[TestCase(TestFiles.png0Rgba32, TestFiles.png0Rgba32, TestFiles.pngPartialTransparent4x4px)]
public void ShouldVerifyThatImageWithDifferentSizeThrows(string pathPic1, string pathPic2, string pathPic3)
{
var sut = new ImageCompare();
Expand Down
2 changes: 1 addition & 1 deletion SkiaSharpCompareTestNunit/SkiaSharpStaticCompareTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ public void ShouldCalcDiffMaskSKBitmapAndUseOutcome(string pathPic1, string path
Assert.That(maskedDiff.PixelErrorPercentage, Is.EqualTo(expectedPixelErrorPercentage), "PixelErrorPercentage");
}

[TestCase(TestFiles.pngWhite2x2px, TestFiles.pngBlack2x2px, TestFiles.pngTransparent2x2px, 765, 12240, 16, 100d, ResizeOption.Resize, 0)]
[TestCase(TestFiles.pngWhite2x2px, TestFiles.pngBlack2x2px, TestFiles.pngTransparent4x4px, 765, 12240, 16, 100d, ResizeOption.Resize, 0)]
[TestCase(TestFiles.pngWhite2x2px, TestFiles.pngBlack2x2px, TestFiles.pngBlack4x4px, 765, 12240, 16, 100d, ResizeOption.Resize, 0)]
[TestCase(TestFiles.pngBlack2x2px, TestFiles.pngBlack2x2px, TestFiles.pngBlack4x4px, 0, 0, 0, 0, ResizeOption.Resize, 0)]
[TestCase(TestFiles.pngBlack2x2px, TestFiles.pngBlack4x4px, TestFiles.pngBlack2x2px, 0, 0, 0, 0, ResizeOption.Resize, 0)]
Expand Down
4 changes: 2 additions & 2 deletions SkiaSharpCompareTestNunit/TestFiles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ internal static class TestFiles
public const string pngBlack2x2px = "./../../../TestData/Black.png";
public const string pngBlack4x4px = "./../../../TestData/BlackDoubleSize.png";
public const string pngWhite2x2px = "./../../../TestData/White.png";
public const string pngTransparent2x2px = "./../../../TestData/pngTransparent2x2px.png";
public const string pngPartialTransparent2x2px = "./../../../TestData/pngPartialTransparent2x2px.png";
public const string pngTransparent4x4px = "./../../../TestData/pngTransparent4x4px.png";
public const string pngPartialTransparent4x4px = "./../../../TestData/pngPartialTransparent4x4px.png";
public const string renderedForm1 = "./../../../TestData/HC007-Test-02-3-OxPt.html1.png";
public const string renderedForm2 = "./../../../TestData/HC007-Test-02-3-OxPt.html2.png";
public const string colorShift1 = "./../../../TestData/ColorShift1.png";
Expand Down
Loading