From 9ee57c561629afa5941c62131151033ba6e7db76 Mon Sep 17 00:00:00 2001 From: Julien Lebosquain Date: Sat, 23 Aug 2025 10:30:04 +0200 Subject: [PATCH] Fix BitmapInterpolationMode.HighQuality when downscaling (#19513) * Fix BitmapInterpolationMode.HighQuality when downscaling * Fix SkiaSharpExtensions.ToSKSamplingOptions public API change --- src/Skia/Avalonia.Skia/DrawingContextImpl.cs | 3 +- src/Skia/Avalonia.Skia/ImmutableBitmap.cs | 6 ++- src/Skia/Avalonia.Skia/SkiaSharpExtensions.cs | 7 +++- src/Skia/Avalonia.Skia/WriteableBitmapImpl.cs | 3 +- .../Avalonia.RenderTests.WpfCompare.csproj | 3 ++ .../CrossUI.Wpf.cs | 12 ++++++ tests/Avalonia.RenderTests/Assets/Star512.png | Bin 0 -> 1877 bytes .../CrossTests/Media/ImageScalingTests.cs | 39 ++++++++++++++++++ .../CrossUI/CrossUI.Avalonia.cs | 1 + tests/Avalonia.RenderTests/CrossUI/CrossUI.cs | 2 + .../Avalonia.Skia.RenderTests.csproj | 3 ++ ..._HighQuality_Should_Be_Antialiased.wpf.png | Bin 0 -> 4621 bytes ..._HighQuality_Should_Be_Antialiased.wpf.png | Bin 0 -> 22924 bytes 13 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 tests/Avalonia.RenderTests/Assets/Star512.png create mode 100644 tests/Avalonia.RenderTests/CrossTests/Media/ImageScalingTests.cs create mode 100644 tests/TestFiles/CrossTests/Media/ImageScaling/Downscaling_With_HighQuality_Should_Be_Antialiased.wpf.png create mode 100644 tests/TestFiles/CrossTests/Media/ImageScaling/Upscaling_With_HighQuality_Should_Be_Antialiased.wpf.png diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index 70d6e2c10f..9ef29a733b 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -244,9 +244,10 @@ namespace Avalonia.Skia var drawableImage = (IDrawableBitmapImpl)source; var s = sourceRect.ToSKRect(); var d = destRect.ToSKRect(); + var isUpscaling = d.Width > s.Width || d.Height > s.Height; var paint = SKPaintCache.Shared.Get(); - var samplingOptions = RenderOptions.BitmapInterpolationMode.ToSKSamplingOptions(); + var samplingOptions = RenderOptions.BitmapInterpolationMode.ToSKSamplingOptions(isUpscaling); paint.Color = new SKColor(255, 255, 255, (byte)(255 * opacity * _currentOpacity)); paint.BlendMode = RenderOptions.BitmapBlendingMode.ToSKBlendMode(); diff --git a/src/Skia/Avalonia.Skia/ImmutableBitmap.cs b/src/Skia/Avalonia.Skia/ImmutableBitmap.cs index c8068fb6fa..802d29b4d0 100644 --- a/src/Skia/Avalonia.Skia/ImmutableBitmap.cs +++ b/src/Skia/Avalonia.Skia/ImmutableBitmap.cs @@ -48,9 +48,10 @@ namespace Avalonia.Skia public ImmutableBitmap(ImmutableBitmap src, PixelSize destinationSize, BitmapInterpolationMode interpolationMode) { + var isUpscaling = destinationSize.Width > src.PixelSize.Width || destinationSize.Height > src.PixelSize.Height; SKImageInfo info = new SKImageInfo(destinationSize.Width, destinationSize.Height, SKColorType.Bgra8888); _bitmap = new SKBitmap(info); - src._image.ScalePixels(_bitmap.PeekPixels(), interpolationMode.ToSKSamplingOptions()); + src._image.ScalePixels(_bitmap.PeekPixels(), interpolationMode.ToSKSamplingOptions(isUpscaling)); _bitmap.SetImmutable(); _image = SKImage.FromBitmap(_bitmap); @@ -95,7 +96,8 @@ namespace Avalonia.Skia if (_bitmap.Width != desired.Width || _bitmap.Height != desired.Height) { - var scaledBmp = _bitmap.Resize(desired, interpolationMode.ToSKSamplingOptions()); + var isUpscaling = desired.Width > _bitmap.Width || desired.Height > _bitmap.Height; + var scaledBmp = _bitmap.Resize(desired, interpolationMode.ToSKSamplingOptions(isUpscaling)); _bitmap.Dispose(); _bitmap = scaledBmp; } diff --git a/src/Skia/Avalonia.Skia/SkiaSharpExtensions.cs b/src/Skia/Avalonia.Skia/SkiaSharpExtensions.cs index 177dbf5cba..4a9502e49e 100644 --- a/src/Skia/Avalonia.Skia/SkiaSharpExtensions.cs +++ b/src/Skia/Avalonia.Skia/SkiaSharpExtensions.cs @@ -10,6 +10,9 @@ namespace Avalonia.Skia public static class SkiaSharpExtensions { public static SKSamplingOptions ToSKSamplingOptions(this BitmapInterpolationMode interpolationMode) + => ToSKSamplingOptions(interpolationMode, true); + + internal static SKSamplingOptions ToSKSamplingOptions(this BitmapInterpolationMode interpolationMode, bool isUpscaling) { return interpolationMode switch { @@ -20,7 +23,9 @@ namespace Avalonia.Skia BitmapInterpolationMode.MediumQuality => new SKSamplingOptions(SKFilterMode.Linear, SKMipmapMode.Linear), BitmapInterpolationMode.HighQuality => - new SKSamplingOptions(SKCubicResampler.Mitchell), + isUpscaling ? + new SKSamplingOptions(SKCubicResampler.Mitchell) : + new SKSamplingOptions(SKFilterMode.Linear, SKMipmapMode.Linear), _ => throw new ArgumentOutOfRangeException(nameof(interpolationMode), interpolationMode, null) }; } diff --git a/src/Skia/Avalonia.Skia/WriteableBitmapImpl.cs b/src/Skia/Avalonia.Skia/WriteableBitmapImpl.cs index 387b84046e..7d8b247ad4 100644 --- a/src/Skia/Avalonia.Skia/WriteableBitmapImpl.cs +++ b/src/Skia/Avalonia.Skia/WriteableBitmapImpl.cs @@ -73,7 +73,8 @@ namespace Avalonia.Skia if (bmp.Width != desired.Width || bmp.Height != desired.Height) { - var scaledBmp = bmp.Resize(desired, interpolationMode.ToSKSamplingOptions()); + var isUpscaling = desired.Width > bmp.Width || desired.Height > bmp.Height; + var scaledBmp = bmp.Resize(desired, interpolationMode.ToSKSamplingOptions(isUpscaling)); bmp.Dispose(); bmp = scaledBmp; } diff --git a/tests/Avalonia.RenderTests.WpfCompare/Avalonia.RenderTests.WpfCompare.csproj b/tests/Avalonia.RenderTests.WpfCompare/Avalonia.RenderTests.WpfCompare.csproj index d20f1b35d3..5925d73962 100644 --- a/tests/Avalonia.RenderTests.WpfCompare/Avalonia.RenderTests.WpfCompare.csproj +++ b/tests/Avalonia.RenderTests.WpfCompare/Avalonia.RenderTests.WpfCompare.csproj @@ -11,6 +11,9 @@ + + + diff --git a/tests/Avalonia.RenderTests.WpfCompare/CrossUI.Wpf.cs b/tests/Avalonia.RenderTests.WpfCompare/CrossUI.Wpf.cs index 633a0fff78..d6e6897d7e 100644 --- a/tests/Avalonia.RenderTests.WpfCompare/CrossUI.Wpf.cs +++ b/tests/Avalonia.RenderTests.WpfCompare/CrossUI.Wpf.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Windows.Media; using System.Windows.Media.Imaging; +using Avalonia.Media.Imaging; using AlignmentX = System.Windows.Media.AlignmentX; using AlignmentY = System.Windows.Media.AlignmentY; using Brush = System.Windows.Media.Brush; @@ -117,6 +118,16 @@ namespace Avalonia.RenderTests.WpfCompare public static WRect ToWpf(this Rect rect) => new(rect.Left, rect.Top, rect.Width, rect.Height); public static WColor ToWpf(this Color color) => WColor.FromArgb(color.A, color.R, color.G, color.B); public static WMatrix ToWpf(this Matrix m) => new WMatrix(m.M11, m.M12, m.M21, m.M22, m.M31, m.M32); + + public static BitmapScalingMode ToWpf(this BitmapInterpolationMode mode) => mode switch + { + BitmapInterpolationMode.Unspecified => BitmapScalingMode.Unspecified, + BitmapInterpolationMode.None => BitmapScalingMode.NearestNeighbor, + BitmapInterpolationMode.LowQuality => BitmapScalingMode.LowQuality, + BitmapInterpolationMode.MediumQuality => BitmapScalingMode.Linear, + BitmapInterpolationMode.HighQuality => BitmapScalingMode.HighQuality, + _ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null) + }; } internal class WpfCrossControl : Panel @@ -131,6 +142,7 @@ namespace Avalonia.RenderTests.WpfCompare Width = src.Bounds.Width; Height = src.Bounds.Height; RenderTransform = new MatrixTransform(src.RenderTransform.ToWpf()); + RenderOptions.SetBitmapScalingMode(this, src.BitmapInterpolationMode.ToWpf()); foreach (var ch in src.Children) { var c = _children[ch]; diff --git a/tests/Avalonia.RenderTests/Assets/Star512.png b/tests/Avalonia.RenderTests/Assets/Star512.png new file mode 100644 index 0000000000000000000000000000000000000000..cf863fdf9e90b415a50615cd0d1923594ca2fca1 GIT binary patch literal 1877 zcmW+%Yfw|?7Tw=D$w`POBtgYQUg2>otwB=o(L$6XL_jWLuv&2_5NZ$wA5pl1SH%;7 zh%Hi#0x3lvVnIM4rBf}phzDvF3bj(vQm}2PqlT)OUIpR$;2!&9&swwB-h1uYGv9ni zH8BxF!F&M#2vs#E0$w_@uhlr^`92exc4&p5}M9Mtr!iR%IS|9v0~8Bzh3L zxqaHwMRfSO%(lL%Z)?W%o8ex-22lu|ELr?21D1bb<>Vylv1y%`=O8k_46j7-_=w zT*qO!9l4-{;g^feozBWWh`!XoQ7G1|f$`c{Z?T&`RDNkbKb83&6s?ZT#Imip-sMz| ztNvdvGKrjTjyiH)b#M-h2i+SP;uT&<^|0@ql|Z#!u>G61?d*LDp1-#}{>Y9pQ=}nu zJJ0Sxtu^Xa(3RxCLFk=SPr-lVgY7E1h`fU`b#|WpH_0dr2dcB+kt}otJxTtE+j^Al zR0J_2jEhGZZ2ELCn;v~Kuw|H@nEmwy^vPQ7&SQF3=wBc%4^TgM@EMVgLV4gh?$$oL zFBMND(dWrJSR*s}QSTXxXI(#;yd1GdVP(BPD`#M#@p+hfx6v9yE!`mzSVz3(SO=VI zAe~KfcIRP>Qwmz3c%@SfBuWt-OB4b>umg$nBv26JjA)Q8TC8?sh%z(;l(r%F9_ zpp#XyCa;aMAx}m^8##c<`@{j*>C_id@NB*n(aPKf^ai%in&t(sCAMZEbdw^sUd1B8 z8tYJT3SY*O5~Skwv%_w)c1lvLlZXqVjaI4LWfO)(!P6&P4e&;53g4f=2p7FDXw#o(gcb8lqHOwyFCr|a~}#|3#Ry!n2K;o zaQ+}DRhq|?e>sNTtGEcvjwi2PT1S02(bv*lG~=JiIdvI%6}8+dLOaOt zQFhUkqty|g70A_Y#lsw2M9d$;P`D>MJr_;7jy@-YMb@PLW%%alSlrq&ZM+k9oTujr zo2ksZsY}GW|Kqy=pC?BhI}Um)yH|6?*Cfi^6xz*e&IW;c<24<16lB@j;0T5cTmJV0 zo~W8&_Pny1lN*tq`;LVE>qIkA_vHSSu5a^kd1$Ykqf)JHghNGi*4-a!VAglki)JxTr6i$k{@Q)5E~!ImT2& z_wPqNf6XW4m`)2HCN3QWcQ3{|8jj&?I|&jwj TestHighQualityScaling(1024); + + [CrossFact] + public void Downscaling_With_HighQuality_Should_Be_Antialiased() + => TestHighQualityScaling(128); + + private void TestHighQualityScaling(int size, [CallerMemberName] string? testName = null) + { + var directoryPath = Path.GetDirectoryName(typeof(ImageScalingTests).Assembly.Location); + var imagePath = Path.Join(directoryPath, "Assets", "Star512.png"); + + RenderAndCompare( + new CrossImageControl + { + Width = size, + Height = size, + Image = new CrossBitmapImage(imagePath), + BitmapInterpolationMode = BitmapInterpolationMode.HighQuality + }, + testName); + } +} diff --git a/tests/Avalonia.RenderTests/CrossUI/CrossUI.Avalonia.cs b/tests/Avalonia.RenderTests/CrossUI/CrossUI.Avalonia.cs index f3ec416ad1..15c6bbac3e 100644 --- a/tests/Avalonia.RenderTests/CrossUI/CrossUI.Avalonia.cs +++ b/tests/Avalonia.RenderTests/CrossUI/CrossUI.Avalonia.cs @@ -105,6 +105,7 @@ namespace Avalonia.Direct2D1.RenderTests.CrossUI Height = src.Bounds.Height; RenderTransform = new MatrixTransform(src.RenderTransform); RenderTransformOrigin = new RelativePoint(default, RelativeUnit.Relative); + RenderOptions = RenderOptions with { BitmapInterpolationMode = src.BitmapInterpolationMode }; foreach (var ch in src.Children) { var c = _children[ch]; diff --git a/tests/Avalonia.RenderTests/CrossUI/CrossUI.cs b/tests/Avalonia.RenderTests/CrossUI/CrossUI.cs index 7c690fc824..fbf55036ed 100644 --- a/tests/Avalonia.RenderTests/CrossUI/CrossUI.cs +++ b/tests/Avalonia.RenderTests/CrossUI/CrossUI.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using Avalonia.Media; using Avalonia; +using Avalonia.Media.Imaging; namespace CrossUI; @@ -229,6 +230,7 @@ public class CrossControl public CrossPen? Outline; public List Children = new(); public Matrix RenderTransform = Matrix.Identity; + public BitmapInterpolationMode BitmapInterpolationMode; public virtual void Render(ICrossDrawingContext ctx) { diff --git a/tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj b/tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj index 233160bd36..7fcc6975a9 100644 --- a/tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj +++ b/tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj @@ -18,6 +18,9 @@ + + + diff --git a/tests/TestFiles/CrossTests/Media/ImageScaling/Downscaling_With_HighQuality_Should_Be_Antialiased.wpf.png b/tests/TestFiles/CrossTests/Media/ImageScaling/Downscaling_With_HighQuality_Should_Be_Antialiased.wpf.png new file mode 100644 index 0000000000000000000000000000000000000000..17b2579f0d04f64ae58077e7d64e01d560de2caa GIT binary patch literal 4621 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 Zwi&nn+MjNJ1pI{q-PShLs@JfK`XA4JX4C)x literal 0 HcmV?d00001 diff --git a/tests/TestFiles/CrossTests/Media/ImageScaling/Upscaling_With_HighQuality_Should_Be_Antialiased.wpf.png b/tests/TestFiles/CrossTests/Media/ImageScaling/Upscaling_With_HighQuality_Should_Be_Antialiased.wpf.png new file mode 100644 index 0000000000000000000000000000000000000000..5d054f1b6e45303b2862c4649a57964d8a889f84 GIT binary patch literal 22924 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 t0D=ZNQOxcgv747|m