Skip to content

Add Pixel Comparer demo to Blazor sample with documentation#371

Merged
mattleibow merged 5 commits intomainfrom
copilot/add-pixel-comparer-to-sample
Mar 3, 2026
Merged

Add Pixel Comparer demo to Blazor sample with documentation#371
mattleibow merged 5 commits intomainfrom
copilot/add-pixel-comparer-to-sample

Conversation

Copy link
Contributor

Copilot AI commented Mar 3, 2026

Adds an interactive SKPixelComparer demo page to the Blazor sample app and corresponding conceptual documentation.

Blazor sample (samples/SkiaSharpDemo.Blazor/)

  • New PixelComparer.razor page: side-by-side image display, rendered difference mask via SKCanvasView, and comparison statistics card
  • Dropdown to switch between image pairs (PNG, JPEG, cross-format), disabled during async comparison with inline spinner
  • Error handling: clears stale results and displays an alert on failure
  • IDisposable cleanup for the SKImage diff mask
  • Nav menu and home page entries
  • Test images copied to wwwroot/images/Comparer/

Documentation (docs/)

  • New docs/docs/pixel-comparer.md — conceptual page covering basic comparison, difference mask generation, mask-based tolerance comparison, input overloads, and visual regression testing patterns
  • Added to docs/docs/toc.yml under SkiaSharp.Extended
  • Added to docs/index.md overview

Usage

var result = SKPixelComparer.Compare("expected.png", "actual.png");
Assert.True(result.ErrorPixelPercentage < 0.005,
    $"Too many differing pixels: {result.ErrorPixelPercentage:P2}");

using var mask = SKPixelComparer.GenerateDifferenceMask("expected.png", "actual.png");

Pixel Comparer page


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

- New PixelComparer.razor page with image pair selection, side-by-side
  display, difference mask canvas, and comparison result stats
- Copy test comparison images to wwwroot/images/Comparer
- Add nav entry and home page card

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
Copilot AI changed the title [WIP] Add pixel comparer to Blazor sample Add Pixel Comparer demo to Blazor sample Mar 3, 2026
@mattleibow mattleibow marked this pull request as ready for review March 3, 2026 15:50
@mattleibow mattleibow requested a review from Copilot March 3, 2026 15:50
github-actions bot pushed a commit that referenced this pull request Mar 3, 2026
@github-actions
Copy link

github-actions bot commented Mar 3, 2026

📖 Documentation Preview

The documentation for this PR has been deployed and is available at:

🔗 View Staging Documentation

🔗 View Staging Blazor Sample

This preview will be updated automatically when you push new commits to this PR.


This comment is automatically updated by the documentation staging workflow.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Blazor WebAssembly demo page to showcase SKPixelComparer in the SkiaSharp.Extended sample site, including side-by-side image viewing, a rendered difference mask, and comparison statistics.

Changes:

  • Added PixelComparer demo page that downloads two images, runs SKPixelComparer.Compare(), and renders GenerateDifferenceMask() via SKCanvasView.
  • Added a new navigation link and Home card entry for the demo.
  • Added image fixtures under wwwroot/images/Comparer/ for the comparisons.

Reviewed changes

Copilot reviewed 4 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
samples/SkiaSharpDemo.Blazor/Pages/PixelComparer.razor New demo page implementing image selection, compare/mask generation, and stats display
samples/SkiaSharpDemo.Blazor/Pages/Home.razor Adds a “Pixel Comparer” demo card linking to the new page
samples/SkiaSharpDemo.Blazor/Layout/NavMenu.razor Adds nav entry for the Pixel Comparer page
samples/SkiaSharpDemo.Blazor/Layout/NavMenu.razor.css Adds a new nav icon style (.bi-eye-nav-menu)
samples/SkiaSharpDemo.Blazor/wwwroot/images/Comparer/First.png Adds PNG fixture image (high-resolution screenshot)
samples/SkiaSharpDemo.Blazor/wwwroot/images/Comparer/Second.png Adds PNG fixture image (high-resolution screenshot)
samples/SkiaSharpDemo.Blazor/wwwroot/images/Comparer/First.jpg Adds JPEG fixture image
samples/SkiaSharpDemo.Blazor/wwwroot/images/Comparer/Second.jpg Adds JPEG fixture image

… alt text, implement IDisposable

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
Copilot AI changed the title Add Pixel Comparer demo to Blazor sample Add Pixel Comparer demo to Blazor sample with documentation Mar 3, 2026
@mattleibow mattleibow requested a review from Copilot March 3, 2026 22:34
@mattleibow mattleibow merged commit bedc9ad into main Mar 3, 2026
4 checks passed
@mattleibow mattleibow deleted the copilot/add-pixel-comparer-to-sample branch March 3, 2026 22:35
github-actions bot pushed a commit that referenced this pull request Mar 3, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 11 changed files in this pull request and generated 2 comments.

Comment on lines +16 to +17
<label class="form-label">Image Pair</label>
<select class="form-select" @bind="selectedPairIndex" @bind:after="OnPairChanged" disabled="@isLoading">
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The is not associated with the (missing for/id), which makes the dropdown harder to use with screen readers and reduces click/target usability. Add an id to the select and a matching for on the label (or wrap the select in the label). <label class="form-label" for="imagePairSelect">Image Pair</label> <select id="imagePairSelect" class="form-select" @Bind="selectedPairIndex" @Bind:after="OnPairChanged" disabled="@isloading">

Copilot uses AI. Check for mistakes.
Comment on lines +139 to +150
if (firstBitmap != null && secondBitmap != null)
{
using var firstImage = SKImage.FromBitmap(firstBitmap);
using var secondImage = SKImage.FromBitmap(secondBitmap);

result = SKPixelComparer.Compare(firstImage, secondImage);

diffMask?.Dispose();
diffMask = SKPixelComparer.GenerateDifferenceMask(firstImage, secondImage);

diffCanvas?.Invalidate();
}
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If SKBitmap.Decode(...) returns null (decode failure), the method silently leaves the previous result/diffMask on screen with no error. Handle the null case by clearing the UI state and setting an error message.

Also, you can avoid extra allocations by using the existing SKPixelComparer.Compare(SKBitmap, SKBitmap) and GenerateDifferenceMask(SKBitmap, SKBitmap) overloads instead of converting bitmaps to SKImage first.

Suggested change
if (firstBitmap != null && secondBitmap != null)
{
using var firstImage = SKImage.FromBitmap(firstBitmap);
using var secondImage = SKImage.FromBitmap(secondBitmap);
result = SKPixelComparer.Compare(firstImage, secondImage);
diffMask?.Dispose();
diffMask = SKPixelComparer.GenerateDifferenceMask(firstImage, secondImage);
diffCanvas?.Invalidate();
}
if (firstBitmap == null || secondBitmap == null)
{
Console.WriteLine("Error comparing images: failed to decode one or both images.");
errorMessage = "Error comparing images: failed to decode one or both images.";
result = null;
diffMask?.Dispose();
diffMask = null;
diffCanvas?.Invalidate();
return;
}
result = SKPixelComparer.Compare(firstBitmap, secondBitmap);
diffMask?.Dispose();
diffMask = SKPixelComparer.GenerateDifferenceMask(firstBitmap, secondBitmap);
diffCanvas?.Invalidate();

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants