Skip to content

Commit 81e55a4

Browse files
authored
Merge pull request #16816 from ramezgerges/imagebrush_downscaling_blur
fix(imagebrush): downscaling images was very blurry
2 parents 18022fd + a124067 commit 81e55a4

File tree

4 files changed

+56
-11
lines changed

4 files changed

+56
-11
lines changed
Loading

src/SamplesApp/UITests.Shared/UITests.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9602,6 +9602,7 @@
96029602
<Content Include="$(MSBuildThisFileDirectory)Assets\RemoteFonts\antikytheraoutline.woff" />
96039603
<Content Include="$(MSBuildThisFileDirectory)Assets\RemoteFonts\antikytheraoutlineital.woff" />
96049604
<Content Include="$(MSBuildThisFileDirectory)Assets\RemoteFonts\GALACTIC VANGUARDIAN NCV.woff" />
9605+
<Content Include="$(MSBuildThisFileDirectory)Assets\ResizedLargeWisteria.png" />
96059606
<Content Include="$(MSBuildThisFileDirectory)Assets\square100.png" />
96069607
<Content Include="$(MSBuildThisFileDirectory)Assets\testimage_exif_rotated.jpg" />
96079608
<Content Include="$(MSBuildThisFileDirectory)Assets\test_image_200_200.png" />

src/Uno.UI.Composition/Composition/CompositionSurfaceBrush.skia.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,20 @@ internal override void UpdatePaint(SKPaint fillPaint, SKRect bounds)
7979
{
8080
if (TryGetSkiaCompositionSurface(Surface, out var scs))
8181
{
82-
var sourceImageSize = new Size(scs.Image!.Width, scs.Image.Height);
83-
var backgroundArea = GetArrangedImageRect(sourceImageSize, bounds);
84-
var matrix = Matrix3x2.CreateScale((float)(backgroundArea.Width / sourceImageSize.Width), (float)(backgroundArea.Height / sourceImageSize.Height));
85-
matrix *= Matrix3x2.CreateTranslation((float)backgroundArea.Left, (float)backgroundArea.Top);
82+
var backgroundArea = GetArrangedImageRect(new Size(scs.Image!.Width, scs.Image.Height), bounds);
83+
84+
// Adding image downscaling in the shader matrix directly is very blurry
85+
// since the default downsampler in Skia is really low quality (but really fast).
86+
// We force Lanczos instead.
87+
// https://github.com/mono/SkiaSharp/issues/520#issuecomment-444973518
88+
#pragma warning disable CS0612 // Type or member is obsolete
89+
var resizedBitmap = scs.Image.ToSKBitmap().Resize(scs.Image.Info.WithSize((int)backgroundArea.Size.Width, (int)backgroundArea.Size.Height), SKBitmapResizeMethod.Lanczos3.ToFilterQuality());
90+
#pragma warning restore CS0612 // Type or member is obsolete
91+
var resizedImage = SKImage.FromBitmap(resizedBitmap);
92+
93+
var matrix = Matrix3x2.CreateTranslation((float)backgroundArea.Left, (float)backgroundArea.Top);
8694
matrix *= TransformMatrix;
87-
88-
var imageShader = SKShader.CreateImage(scs.Image, SKShaderTileMode.Decal, SKShaderTileMode.Decal, matrix.ToSKMatrix());
95+
var imageShader = SKShader.CreateImage(resizedImage, SKShaderTileMode.Decal, SKShaderTileMode.Decal, matrix.ToSKMatrix());
8996

9097
if (UsePaintColorToColorSurface)
9198
{

src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media/Given_ImageBrushStretch.cs renamed to src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media/Given_ImageBrush.cs

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Media
1515
{
1616
[TestClass]
1717
[RunsOnUIThread]
18-
public class Given_ImageBrushStretch
18+
public class Given_ImageBrush
1919
{
2020
[DataRow(Stretch.Fill, false)]
2121
[DataRow(Stretch.Fill, true)]
@@ -100,10 +100,47 @@ public async Task When_Stretch(Stretch stretch, bool useRectangle)
100100

101101
var bitmap = await UITestHelper.ScreenShot(SUT);
102102

103-
ImageAssert.HasColorAt(bitmap, centerX, BorderOffset, expectations.Top, tolerance: 21);
104-
ImageAssert.HasColorAt(bitmap, centerX, height - BorderOffset, expectations.Bottom, tolerance: 21);
105-
ImageAssert.HasColorAt(bitmap, BorderOffset, centerY, expectations.Left, tolerance: 21);
106-
ImageAssert.HasColorAt(bitmap, width - BorderOffset, centerY, expectations.Right, tolerance: 21);
103+
ImageAssert.HasColorAt(bitmap, centerX, BorderOffset, expectations.Top, tolerance: 28);
104+
ImageAssert.HasColorAt(bitmap, centerX, height - BorderOffset, expectations.Bottom, tolerance: 28);
105+
ImageAssert.HasColorAt(bitmap, BorderOffset, centerY, expectations.Left, tolerance: 28);
106+
ImageAssert.HasColorAt(bitmap, width - BorderOffset, centerY, expectations.Right, tolerance: 28);
107107
}
108+
109+
#if __SKIA__
110+
[TestMethod]
111+
public async Task When_DownSampling()
112+
{
113+
var border = new Border
114+
{
115+
Width = 100,
116+
Height = 100,
117+
Background = new ImageBrush
118+
{
119+
ImageSource = new Uri("ms-appx:/Assets/LargeWisteria.jpg")
120+
}
121+
};
122+
123+
var image = new Image
124+
{
125+
Width = 100,
126+
Height = 100,
127+
Source = new Uri("ms-appx:/Assets/ResizedLargeWisteria.png")
128+
};
129+
130+
await UITestHelper.Load(new StackPanel
131+
{
132+
Children =
133+
{
134+
border,
135+
image
136+
}
137+
});
138+
await Task.Delay(1000); // wait for idle might not be enough here
139+
140+
var bitmap = await UITestHelper.ScreenShot(border);
141+
var bitmap2 = await UITestHelper.ScreenShot(image);
142+
await ImageAssert.AreEqualAsync(bitmap, bitmap2);
143+
}
144+
#endif
108145
}
109146
}

0 commit comments

Comments
 (0)