Skip to content

Fix downscaled raster export filtering#516

Merged
wieslawsoltes merged 3 commits into
masterfrom
fix/issue-246-downsample-raster
May 9, 2026
Merged

Fix downscaled raster export filtering#516
wieslawsoltes merged 3 commits into
masterfrom
fix/issue-246-downsample-raster

Conversation

@wieslawsoltes
Copy link
Copy Markdown
Owner

PR Summary: Fix Downscaled Raster Export Filtering

Summary

Fixes raster image export at very small scales, where filter effects such as feMorphology could disappear because the SVG picture was rendered directly into the final low-resolution target.

The raster export path now renders downscaled images through a bounded higher-resolution intermediate surface and then downsamples to the requested output size. This preserves subpixel filtered detail while avoiding unbounded memory use for very large SVG documents.

Problem

Issue #246 reported that an SVG rendered with Svg.Save at a small target size lost the white inside stroke produced by a filter using feMorphology radius="8".

The affected export scale was approximately 38 / 609. Rendering directly at that scale made the morphology kernel too small in the target raster, so the filter output was effectively lost.

Changes

  • Added a downsample-aware raster export path for SKPictureExtensions.ToBitmap.
  • Added the same downsample-aware raster export path for SKPictureExtensions.ToImage.
  • Extracted image encoding into a shared helper to keep direct and downsampled image paths consistent.
  • Added render-scale selection that prefers a full 1x intermediate when it fits the raster budget.
  • Added a 4x oversample fallback for documents where full 1x rendering would be too large.
  • Added a 16M-pixel maximum intermediate raster budget.
  • Added a final bounded oversample calculation for large requested output sizes.
  • Kept direct rendering when the requested target itself is already at or above the raster budget.
  • Used SKBlendMode.Src when drawing the intermediate image into the target, so translucent backgrounds are copied exactly instead of being composited twice.

Tests

Added focused SKSvgTests coverage for:

  • preserving the white inside stroke in the issue-style downscaled morphology filter case;
  • exporting a very large downscaled SVG without trying to allocate an unbounded full-size intermediate surface;
  • preserving a translucent background through the downsample path without double compositing.

Validation

Commands run locally:

dotnet format src/Svg.Skia/Svg.Skia.csproj --no-restore --include src/Svg.Skia/SKPictureExtensions.cs
dotnet format tests/Svg.Skia.UnitTests/Svg.Skia.UnitTests.csproj --no-restore --include tests/Svg.Skia.UnitTests/SKSvgTests.cs
dotnet test tests/Svg.Skia.UnitTests/Svg.Skia.UnitTests.csproj -f net10.0 -c Release --no-restore --filter "FullyQualifiedName~SKSvgTests" --logger "console;verbosity=normal"
dotnet build Svg.Skia.slnx -c Release
dotnet test Svg.Skia.slnx -c Release --no-build --logger "console;verbosity=normal"
git diff --check

Results:

  • Focused SKSvgTests: 10 passed.
  • Full release build: passed with existing warnings.
  • Full test suite: 2231 total, 1638 passed, 593 skipped.
  • git diff --check: clean.

Commits

  • fc71bdf2b Fix downscaled raster export filtering
  • 1f00bc87d Add downscaled export regressions

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant