Skip to content

Add configurable ResizeQuality for Resizetizer#34559

Open
jfversluis wants to merge 8 commits intonet11.0from
feature/resizetizer-configurable-filter-quality
Open

Add configurable ResizeQuality for Resizetizer#34559
jfversluis wants to merge 8 commits intonet11.0from
feature/resizetizer-configurable-filter-quality

Conversation

@jfversluis
Copy link
Copy Markdown
Member

@jfversluis jfversluis commented Mar 19, 2026

Description

Adds a configurable ResizeQuality option to Resizetizer, allowing developers to control the image resampling quality when resizing images. This is a clean re-implementation of community PR #25686 (by @thisisthekap), rebased onto net11.0 and incorporating review feedback from @mattleibow.

Key changes:

  • New ResizeQuality enum with three values: Auto (default), Best, Fastest
  • Maps to SKSamplingOptions (not the deprecated Paint.FilterQuality which is ignored by newer SkiaSharp)
  • MSBuild metadata: <MauiImage ResizeQuality="Fastest" ... />
  • Zero behavior change for existing usersAuto produces identical output to the previous hardcoded behavior

Quality mappings:

ResizeQuality SKSamplingOptions Use case
Auto (default) Linear + Linear mipmaps Same as previous behavior
Best Mitchell cubic resampler Highest quality downscaling
Fastest Nearest neighbor, no mipmaps Fast builds, pixel art

Usage:

<MauiImage Include="Resources\Images\photo.png" ResizeQuality="Fastest" />

Changes

9 source files across Resizetizer:

  • ResizeQuality.cs (new) — Custom enum
  • ResizeImageInfo.cs — Quality property + case-insensitive MSBuild metadata parsing
  • SkiaSharpTools.cs — ResizeQuality → SKSamplingOptions mapping; removed obsolete Paint.FilterQuality
  • SkiaSharpRasterTools.cs, SkiaSharpSvgTools.cs, SkiaSharpImaginaryTools.cs — Constructor chains
  • Resizer.cs, SkiaSharpAppIconTools.cs, AndroidAdaptiveIconGenerator.cs — Pass quality through

4 test files with 37 new tests:

  • SamplingOptions correctness tests (all 3 qualities map correctly)
  • Functional pixel-comparison tests (different qualities produce different output)
  • Regression tests (default == explicit Auto, pixel-identical)
  • End-to-end MSBuild pipeline tests
  • Case-insensitive parsing tests

Test results

  • 605 passed, 20 failed (pre-existing AppIconTools failures), 0 regressions
  • All 37 new tests pass ✅

Review notes

Addresses feedback from @mattleibow on #25686:

  • ✅ Uses custom enum instead of exposing SkiaSharp's deprecated SKFilterQuality
  • ✅ Maps to SKSamplingOptions (the actual rendering control, not the ignored Paint.FilterQuality)
  • Best uses SKCubicResampler.Mitchell as suggested

Items for reviewer consideration:

  • Enum naming (Auto/Best/Fastest) — open to alternatives like Default/High/Low
  • TizenSplashUpdater has its own hardcoded quality (separate code path, out of scope)

Fixes #25686

Copilot AI review requested due to automatic review settings March 19, 2026 09:40
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 19, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34559

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34559"

@jfversluis jfversluis requested a review from mattleibow March 19, 2026 09:44
@jfversluis jfversluis added the area-single-project Splash Screen, Multi-Targeting, MauiFont, MauiImage, MauiAsset, Resizetizer label Mar 19, 2026
Copy link
Copy Markdown
Contributor

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

This PR adds a configurable ResizeQuality option to Resizetizer so image resampling quality can be controlled via MSBuild metadata, while keeping existing behavior unchanged by default (Auto).

Changes:

  • Introduces an internal ResizeQuality enum and plumbs it through ResizeImageInfo → tool creation → resize operations.
  • Replaces use of obsolete SKPaint.FilterQuality with explicit SKSamplingOptions selection based on ResizeQuality.
  • Adds unit + end-to-end tests validating parsing, sampling-option mapping, and output differences/regressions.

Reviewed changes

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

Show a summary per file
File Description
src/SingleProject/Resizetizer/src/ResizeQuality.cs Adds the ResizeQuality enum used to control resampling behavior.
src/SingleProject/Resizetizer/src/ResizeImageInfo.cs Adds Quality property + parses ResizeQuality MSBuild metadata.
src/SingleProject/Resizetizer/src/SkiaSharpTools.cs Adds quality-aware factory/ctor and maps ResizeQuality to SKSamplingOptions.
src/SingleProject/Resizetizer/src/SkiaSharpRasterTools.cs Passes quality through constructor chain; raster draw uses SamplingOptions.
src/SingleProject/Resizetizer/src/SkiaSharpSvgTools.cs Passes quality through; uses SamplingOptions for raster downscaling path.
src/SingleProject/Resizetizer/src/SkiaSharpImaginaryTools.cs Updates base ctor call to include default quality.
src/SingleProject/Resizetizer/src/SkiaSharpAppIconTools.cs Ensures app icon background/foreground tool creation respects info.Quality.
src/SingleProject/Resizetizer/src/Resizer.cs Threads Info.Quality into tool creation.
src/SingleProject/Resizetizer/src/AndroidAdaptiveIconGenerator.cs Threads Info.Quality into adaptive icon resizing.
src/SingleProject/Resizetizer/test/UnitTests/ResizeImageInfoTests.cs Adds tests for defaulting + case-insensitive parsing + invalid value handling.
src/SingleProject/Resizetizer/test/UnitTests/SkiaSharpRasterToolsTests.cs Adds sampling-option mapping tests and functional output comparisons for raster images.
src/SingleProject/Resizetizer/test/UnitTests/SkiaSharpSvgToolsTests.cs Adds sampling-option mapping tests and functional output comparisons for SVG downscaling.
src/SingleProject/Resizetizer/test/UnitTests/ResizetizeImagesTests.cs Adds end-to-end MSBuild task pipeline tests for ResizeQuality.

You can also share your feedback on Copilot code review. Take the survey.

@jfversluis jfversluis requested a review from Copilot March 19, 2026 09:50
Copy link
Copy Markdown
Contributor

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

This PR adds a configurable ResizeQuality option to the Resizetizer pipeline so callers can control image resampling behavior (via MSBuild item metadata), while preserving the existing default output.

Changes:

  • Introduces an internal ResizeQuality enum and plumbs it through ResizeImageInfo parsing and all resizing/tooling entry points.
  • Switches resampling control to SKSamplingOptions (removing the obsolete SKPaint.FilterQuality usage) and maps ResizeQuality values to the desired sampling options.
  • Adds unit and end-to-end tests covering parsing, sampling option mapping, and output equivalence/differences.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/SingleProject/Resizetizer/src/ResizeQuality.cs Adds the new ResizeQuality enum used to select resampling behavior.
src/SingleProject/Resizetizer/src/ResizeImageInfo.cs Adds Quality with default, and parses ResizeQuality from MSBuild metadata.
src/SingleProject/Resizetizer/src/SkiaSharpTools.cs Plumbs ResizeQuality into constructors/factories and maps it to SKSamplingOptions; removes obsolete FilterQuality.
src/SingleProject/Resizetizer/src/SkiaSharpRasterTools.cs Threads quality through constructors so raster drawing uses the configured sampling.
src/SingleProject/Resizetizer/src/SkiaSharpSvgTools.cs Threads quality through constructors so SVG downscaling uses the configured sampling.
src/SingleProject/Resizetizer/src/SkiaSharpImaginaryTools.cs Updates base constructor call to provide a default ResizeQuality for manufactured images.
src/SingleProject/Resizetizer/src/Resizer.cs Ensures ResizeQuality flows into SkiaSharpTools.Create(...) when resizing.
src/SingleProject/Resizetizer/src/SkiaSharpAppIconTools.cs Ensures app icon background/foreground tool creation passes through ResizeQuality.
src/SingleProject/Resizetizer/src/AndroidAdaptiveIconGenerator.cs Ensures adaptive icon background/foreground resizing passes through ResizeQuality.
src/SingleProject/Resizetizer/test/UnitTests/ResizeImageInfoTests.cs Adds tests for defaulting and case-insensitive parsing of ResizeQuality metadata.
src/SingleProject/Resizetizer/test/UnitTests/SkiaSharpRasterToolsTests.cs Adds tests validating sampling option mapping and output invariants/differences for raster resizing.
src/SingleProject/Resizetizer/test/UnitTests/SkiaSharpSvgToolsTests.cs Adds tests validating sampling option mapping and output invariants/differences for SVG resizing.
src/SingleProject/Resizetizer/test/UnitTests/ResizetizeImagesTests.cs Adds end-to-end MSBuild pipeline tests verifying metadata is respected and defaults preserve baseline behavior.

You can also share your feedback on Copilot code review. Take the survey.

@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Apr 3, 2026

Code Review Summary

ResizeQuality for Resizetizer — Adds Auto/Best/Fastest quality options, replaces deprecated Paint.FilterQuality with SKSamplingOptions. 37 new tests including pixel-comparison regression tests. Backward compatible (Auto = previous behavior).

Findings

Severity Finding
🔴 Critical Missing </summary> closing tag on Best enum member XML doc in ResizeQuality.cs
🔴 Critical MSBuild incremental build won't detect ResizeQuality changesResizeQuality=%(ResizeQuality) is missing from the mauiimage.inputs tracking in Microsoft.Maui.Resizetizer.After.targets (line ~328). Users changing quality settings will get stale cached images unless they clean-rebuild
🟡 Warning TizenSplashUpdater.cs still uses deprecated Paint.FilterQuality (acknowledged as out of scope)
🟡 Warning No test for SkiaSharpImaginaryTools with ResizeQuality
🔵 Info Excellent backward compatibility design — Auto maps to identical sampling as previous hardcoded value
🔵 Info 37 tests with pixel-comparison regression coverage is thorough

Overall Assessment

⚠️ Needs two fixes before merge:

  1. Fix the missing </summary> XML doc tag (one-liner)
  2. Add ResizeQuality=%(ResizeQuality) to the MSBuild inputs file to avoid caching bugs

Otherwise the design, test coverage, and backward compatibility story are solid.


Review performed by Copilot CLI

@jfversluis jfversluis added this to the .NET 11.0-preview4 milestone Apr 7, 2026
@jfversluis jfversluis force-pushed the feature/resizetizer-configurable-filter-quality branch from a438af9 to 28be2d7 Compare April 7, 2026 14:23
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Apr 7, 2026

Code Review — PR #34559

Independent Assessment

What this changes: Adds configurable ResizeQuality metadata to Resizetizer, controlling image resampling via SKSamplingOptions. New internal ResizeQuality enum (Auto/Best/Fastest) maps to SkiaSharp sampling strategies. Threaded through all SkiaSharp tool constructors and factory methods. Zero behavior change for default Auto — identical output to previous hardcoded behavior.

Target branch: net11.0 — correct for new feature. Milestone .NET 11.0-preview4.

Reconciliation with PR Narrative

Agreement: ✅ Code matches description. Addresses @mattleibow's feedback on #25686: uses custom enum (not deprecated SKFilterQuality), maps to SKSamplingOptions (the actual rendering control), and Best uses SKCubicResampler.Mitchell.


Findings

✅ Good — Correct SkiaSharp API usage

The old code relied on Paint.FilterQuality which is deprecated and ignored by modern SkiaSharp. The new code explicitly passes SKSamplingOptions to canvas.DrawImage():

// SkiaSharpRasterTools.DrawUnscaled
canvas.DrawImage(img, 0, 0, SamplingOptions, Paint);

// SkiaSharpSvgTools.DrawUnscaled (downscale path)
canvas.DrawImage(img, 0, 0, SamplingOptions, Paint);

SVG upscaling (scale >= 1) correctly skips SamplingOptions — vector rendering is lossless, so canvas.DrawPicture(svg.Picture, Paint) is used directly. ✅

✅ Good — Quality mappings are well-chosen

ResizeQuality SKSamplingOptions Rationale
Auto Linear + Linear mipmaps Matches previous hardcoded behavior exactly
Best SKCubicResampler.Mitchell Industry-standard high-quality cubic resampler
Fastest Nearest, no mipmaps Zero interpolation overhead

✅ Good — Backwards compatible

  • ResizeQuality defaults to Auto via DefaultResizeQuality
  • Auto maps to the same Linear/Linear that was hardcoded before
  • Invalid MSBuild values silently fall back to Auto (via Enum.TryParse returning false)
  • Case-insensitive parsing: ResizeQuality="best" works ✅

✅ Good — Clean constructor threading

Quality parameter added to all constructor chains consistently:

  • SkiaSharpTools.Create(...) factory
  • SkiaSharpRasterTools, SkiaSharpSvgTools constructors
  • SkiaSharpImaginaryTools (passes through but doesn't use — correct, no source image to resample)
  • Resizer, SkiaSharpAppIconTools, AndroidAdaptiveIconGenerator callers

✅ Good — Incremental build support

ResizeQuality added to the _ResizetizerInputsFile line in the MSBuild targets, ensuring build is invalidated when quality changes.

✅ Good — Comprehensive tests (22 new)

  • Sampling options mapping tests for all 3 qualities × both Raster and SVG tools
  • Pixel comparison tests proving different qualities produce different output
  • Regression test: default == explicit Auto (pixel-identical)
  • Case-insensitive parsing tests
  • MSBuild metadata parsing tests

💡 Observation — SkiaSharpImaginaryTools doesn't use quality

SkiaSharpImaginaryTools (used to manufacture solid-color placeholder icons) receives ResizeQuality.Auto from CreateImaginary but never uses it for sampling — its DrawUnscaled likely just fills a solid rect. This is correct but could be documented with a brief comment in CreateImaginary:

// Quality irrelevant for imaginary tools — no source image to resample

💡 Observation — Silent fallback for invalid values

Invalid ResizeQuality metadata (e.g., ResizeQuality="Turbo") silently defaults to Auto. This is user-friendly but could be surprising. A Logger.Log warning for unrecognized values would help developers catch typos:

var rawQuality = image.GetMetadata("ResizeQuality");
if (!string.IsNullOrEmpty(rawQuality) && !Enum.TryParse<ResizeQuality>(rawQuality, ignoreCase: true, out var quality))
    Logger?.Log($"Warning: Unrecognized ResizeQuality {rawQuality}, using Auto.");

Not a blocker — just a nice-to-have for discoverability.

ℹ️ Note — ResizeQuality is internal

The enum is internal — only accessible via MSBuild metadata, not from C# code. This is correct for a build-time configuration. No PublicAPI.Unshipped.txt entries needed.

ℹ️ Note — CI Status

No CI failures detected. Clean build.


Devil's Advocate

  • "Why not expose the SkiaSharp enum directly?"@mattleibow's review on made FilterQuality configurable for Resizetizer #25686 explicitly requested a custom enum because SKFilterQuality is deprecated and SKSamplingOptions is too low-level for MSBuild metadata. The three-value abstraction is the right choice.
  • "Is Mitchell actually better than Linear for app icons?" — Mitchell cubic resampling is the industry standard for high-quality image downscaling (used by ImageMagick, libvips, etc.). For 108px→48px app icon density scaling, it preserves more detail than bilinear. Correct choice.
  • "Could the extra parameter break callers of SkiaSharpTools.Create?" — All internal callers are updated in this PR. The types are internal, so no external consumers exist.
  • "Does Fastest produce unusably bad output?" — For pixel art or development builds, nearest-neighbor is intentional. The PR title/docs make the tradeoff clear. Users opt in explicitly.

Verdict: LGTM

Confidence: high
Summary: Clean re-implementation of community PR #25686 addressing reviewer feedback. Correct SkiaSharp API migration from deprecated Paint.FilterQuality to SKSamplingOptions. Zero behavior change for default users. Well-chosen quality mappings, consistent constructor threading, comprehensive tests. Ready for merge.

Review performed by Copilot CLI using the code-review skill

kubaflo
kubaflo previously approved these changes Apr 7, 2026
jfversluis and others added 8 commits April 9, 2026 12:22
Add a FilterQuality property to ResizeImageInfo with a default of
SKFilterQuality.High (preserving existing behavior). The property is
parsed from MSBuild item metadata and threaded through SkiaSharpTools,
SkiaSharpRasterTools, SkiaSharpSvgTools, SkiaSharpImaginaryTools,
Resizer, SkiaSharpAppIconTools, and AndroidAdaptiveIconGenerator.

Users can now configure FilterQuality per image in their project file:
  <MauiImage Include="Resources\Images\photo.png" FilterQuality="None" />

Fixes #25750

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The original implementation only set Paint.FilterQuality which is deprecated
and ignored by newer SkiaSharp. This fix maps FilterQuality to the actual
SamplingOptions used by DrawImage, making the setting functional:
- None -> Nearest/None (nearest neighbor, smallest file size)
- Low -> Linear/None (bilinear, no mipmaps)
- Medium -> Linear/Linear (bilinear + mipmaps)
- High/default -> Linear/Linear (preserves original hardcoded behavior)

Added 13 functional tests proving the feature works end-to-end:
- Pixel differentiation: None vs High produce different output (proves it works)
- Regression: default produces identical output to explicit High
- End-to-end MSBuild pipeline: FilterQuality metadata flows through ResizetizeImages task
- All quality levels produce correctly sized output for both raster and SVG

Full regression: 605 passed (568 baseline + 37 new), 20 pre-existing failures, 0 regressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Per mattleibow's review on PR #25686, replace the obsolete SKFilterQuality
enum with a clean MAUI-specific ResizeQuality enum that hides SkiaSharp
internals:

- Auto: Default behavior (bilinear + mipmaps, preserves backward compat)
- Best: Mitchell cubic resampler (highest quality)
- Fastest: Nearest neighbor (smallest file size, fastest processing)

MSBuild metadata name changed from FilterQuality to ResizeQuality.
All 25 new tests pass. 593 total passed (568 baseline + 25 new).
Same 20 pre-existing failures. Zero regressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Enum.TryParse now uses ignoreCase: true, matching MSBuild convention
  for metadata parsing (consistent with Resize, TintColor, etc.)
- Added 3 case-insensitive parsing tests (auto, FASTEST, best)
- Added Best vs Auto pixel differentiation test proving Mitchell cubic
  path is exercised and produces different output than bilinear

29 new tests, 597 total passed, 0 regressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ke tests

- Replace meaningless IsAntialias assertions with SamplingOptions correctness checks
- Add per-quality SamplingOptions mapping tests (Auto→Linear/Linear, Best→Mitchell, Fastest→Nearest/None)
- Add SVG pixel differentiation test (Fastest vs Auto on downscale)
- Add Best quality smoke tests for both raster and SVG
- Fix SVG tests to use BaseSize for exact dimension assertions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Assert pixel array lengths match before comparison loop to avoid IndexOutOfRangeException
- Remove misleading 'smaller file sizes' claim from Fastest doc (PNG encoding is fixed)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…alidation

- Add missing </summary> closing tag on Best enum member XML doc
- Add ResizeQuality to MSBuild inputs tracking so changing quality
  settings triggers a rebuild instead of serving stale cached images

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jfversluis jfversluis force-pushed the feature/resizetizer-configurable-filter-quality branch from 28be2d7 to 6989901 Compare April 9, 2026 10:24
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

🧪 PR Test Evaluation

Overall Verdict: ✅ Tests are adequate

This PR adds 37 new unit tests with excellent coverage of the core ResizeQuality feature — sampling options mapping, pixel-level regression testing, case-insensitive parsing, and E2E MSBuild pipeline validation. A few minor gaps exist around app icon code paths that were modified but not directly tested.

👍 / 👎 — Was this evaluation helpful? React to let us know!

📊 Expand Full Evaluation

PR Test Evaluation Report

PR: #34559 — Add configurable ResizeQuality for Resizetizer
Test files evaluated: 4
Fix files: 10 (including new ResizeQuality.cs)


Overall Verdict

Tests are adequate

Strong unit test coverage of the core quality mapping, MSBuild metadata parsing, and pixel-level regression guarantees. Two minor gaps in coverage for the SkiaSharpAppIconTools and AndroidAdaptiveIconGenerator code paths, which were modified but not directly tested.


1. Fix Coverage — ✅

The tests trace directly to the changed code paths:

  • SkiaSharpRasterToolsTests.ResizeQualityTests verifies the SamplingOptions property is set to the correct SKSamplingOptions for each ResizeQuality value — directly testing the switch expression in SkiaSharpTools
  • SkiaSharpSvgToolsTests.ResizeQualityTests mirrors the above for SVG tools
  • ResizeImageInfoTests.ResizeQualityTests directly tests the ResizeImageInfo.Parse() method for MSBuild metadata parsing
  • ResizetizeImagesTests covers the full E2E pipeline: task creation → resize → output file

If the quality mapping switch were reverted, the sampling options correctness tests would fail. If the Enum.TryParse parsing were removed, the QualityParsedFromTaskItem tests would fail.


2. Edge Cases & Gaps — ⚠️

Covered:

  • All three ResizeQuality values (Auto, Best, Fastest) map to correct SKSamplingOptions
  • Default (no quality set) == explicit Auto at pixel level (regression guarantee)
  • Case-insensitive MSBuild metadata parsing (auto, FASTEST, best)
  • Invalid/unrecognized metadata value gracefully defaults to Auto
  • ResizeQualityMetadataIsRespectedEndToEnd — full MSBuild pipeline test
  • Fastest vs Auto produce different pixel output (raster + SVG)
  • Best vs Auto produce different pixel output (raster only)
  • All qualities produce correctly sized output (dimensions)

Missing:

  • SkiaSharpAppIconTools with qualitySkiaSharpAppIconTools was changed to pass info.Quality to SkiaSharpTools.Create for both background and foreground, but there's no test that app icon processing respects ResizeQuality. The existing SkiaSharpAppIconToolsTests are not updated with quality scenarios.
  • AndroidAdaptiveIconGenerator with quality — Similarly, adaptive icon background/foreground now pass Info.Quality, but no test covers this code path.
  • SVG: Best vs Auto pixel comparison missingSkiaSharpSvgToolsTests has DifferentQualitiesProduceDifferentPixelOutput for Fastest vs Auto, but not for Best vs Auto. The raster tests have both comparisons. (Minor: SVG rendering is vector-based so differences may be less predictable, but worth noting.)
  • Build invalidation — The .targets file was updated to include ResizeQuality in the incremental build hash. No test verifies that changing ResizeQuality triggers a rebuild (existing Resizetizer tests don't cover this, and it's a valid gap).

3. Test Type Appropriateness — ✅

Current: Unit Tests (xUnit, [Fact]/[Theory])
Recommendation: Same — this is exactly right.

Resizetizer is a build tool with no platform or UI dependency. All logic (enum mapping, SKSamplingOptions selection, pixel output) is pure, deterministic, and testable in isolation. Unit tests are the correct and optimal choice here.


4. Convention Compliance — ✅

  • Uses xUnit [Fact] and [Theory] with [InlineData]
  • Inner test class organization (e.g., ResizeQualityTests nested inside the existing test class) follows the pattern used elsewhere in the file ✅
  • IDisposable pattern used correctly for temp file cleanup in SkiaSharpRasterToolsTests and SkiaSharpSvgToolsTests
  • Test files are in the correct test project (Resizetizer.UnitTests.csproj) ✅

5. Flakiness Risk — ✅ Low

  • Tests are fully deterministic (no async, no delays, no platform-specific rendering)
  • Pixel comparison tests rely on SkiaSharp's deterministic resampling — low risk for false negatives
  • Minor theoretical risk: Assert.True(differentPixels > 0, ...) could fail if SkiaSharp changes its algorithm or if a test image happened to produce identical output at a given scale. Using a real-world photo (camera.png downscaled to 100×100) makes this unlikely.

6. Duplicate Coverage — ✅ No duplicates

This is a new feature; no existing tests cover ResizeQuality. No overlap detected.


7. Platform Scope — ✅

Resizetizer is a build-time tool with no platform-specific code. Unit tests run cross-platform (Windows, macOS, Linux). The ResizeQuality feature itself works at build time and is platform-agnostic — no additional platform-specific testing is needed.


8. Assertion Quality — ✅

Test Assertion Quality
Sampling options mapping Assert.Equal(new SKSamplingOptions(...), tools.SamplingOptions) ✅ Exact match
Pixel identity (default == Auto) Pixel-by-pixel loop Assert.Equal(pixel1, pixel2) ✅ Very strong
Pixel difference Assert.True(differentPixels > 0, ...) ✅ Adequate with message
Output dimensions Assert.Equal(256, resultImage.Width) ✅ Specific
Enum parsing Assert.Equal(expected, info.Quality) ✅ Exact match

Assertions are specific and meaningful throughout. The pixel-by-pixel equality for the regression test (DefaultQualityProducesIdenticalOutputToExplicitAuto) is particularly strong.


9. Fix-Test Alignment — ✅

Fix → Test mapping:

Changed File Test Coverage
ResizeQuality.cs (new enum) Used in all test files ✅
ResizeImageInfo.cs (Quality property + parsing) ResizeImageInfoTests.ResizeQualityTests
SkiaSharpTools.cs (sampling options switch) SkiaSharpRasterToolsTests.ResizeQualityTests, SkiaSharpSvgToolsTests.ResizeQualityTests
SkiaSharpRasterTools.cs / SkiaSharpSvgTools.cs / SkiaSharpImaginaryTools.cs (constructors) Covered transitively ✅
Resizer.cs (passes quality through) Covered by E2E ResizetizeImagesTests
SkiaSharpAppIconTools.cs (passes quality) ⚠️ Not directly tested
AndroidAdaptiveIconGenerator.cs (passes quality) ⚠️ Not directly tested
Microsoft.Maui.Resizetizer.After.targets (build invalidation) ⚠️ Not directly tested

Recommendations

  1. (Nice-to-have) Add a quality test to SkiaSharpAppIconToolsTests — Add a test that creates an app icon with ResizeQuality=Fastest and verifies the output differs from Auto. Since the existing SkiaSharpAppIconToolsTests already test pixel output, this would be a straightforward addition.
  2. (Nice-to-have) Add SVG Best vs Auto pixel comparison — Mirror BestQualityProducesDifferentPixelOutputThanAuto from SkiaSharpRasterToolsTests in SkiaSharpSvgToolsTests to ensure SVG quality behaves as expected for Best mode.
  3. (Low priority) Consider a ResizeQuality E2E test for app icons — A test in ResizetizeImagesTests that uses an app icon item with ResizeQuality set would close the gap for the AndroidAdaptiveIconGenerator code path.

Warning

⚠️ Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • dc.services.visualstudio.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "dc.services.visualstudio.com"

See Network Configuration for more information.

Note

🔒 Integrity filtering filtered 2 items

Integrity filtering activated and filtered the following items during workflow execution.
This happens when a tool call accesses a resource that does not meet the required integrity or secrecy level of the workflow.

🧪 Test evaluation by Evaluate PR Tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-single-project Splash Screen, Multi-Targeting, MauiFont, MauiImage, MauiAsset, Resizetizer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants