Add Pixel Comparer demo to Blazor sample with documentation#371
Add Pixel Comparer demo to Blazor sample with documentation#371mattleibow merged 5 commits intomainfrom
Conversation
- 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>
|
📖 Documentation Preview The documentation for this PR has been deployed and is available at: This preview will be updated automatically when you push new commits to this PR. This comment is automatically updated by the documentation staging workflow. |
There was a problem hiding this comment.
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
PixelComparerdemo page that downloads two images, runsSKPixelComparer.Compare(), and rendersGenerateDifferenceMask()viaSKCanvasView. - 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>
| <label class="form-label">Image Pair</label> | ||
| <select class="form-select" @bind="selectedPairIndex" @bind:after="OnPairChanged" disabled="@isLoading"> |
There was a problem hiding this comment.
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">
| 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(); | ||
| } |
There was a problem hiding this comment.
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.
| 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(); |
Adds an interactive
SKPixelComparerdemo page to the Blazor sample app and corresponding conceptual documentation.Blazor sample (
samples/SkiaSharpDemo.Blazor/)PixelComparer.razorpage: side-by-side image display, rendered difference mask viaSKCanvasView, and comparison statistics cardIDisposablecleanup for theSKImagediff maskwwwroot/images/Comparer/Documentation (
docs/)docs/docs/pixel-comparer.md— conceptual page covering basic comparison, difference mask generation, mask-based tolerance comparison, input overloads, and visual regression testing patternsdocs/docs/toc.ymlunder SkiaSharp.Extendeddocs/index.mdoverviewUsage
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.