Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bitmap smoothing in UWP

Tags:

c#

xaml

uwp

I am trying to figure out how to resize an image without losing quality in UWP. I know in WPF there's an option to smooth an image using this: RenderOptions.BitmapScalingMode="HighQuality" but I can't seem to find an equivalent in UWP.

Here's what the image looks like:

And what it's supposed to look like:

If you look closely, you can see that the picture is badly pixelated. How can I achieve this in UWP?

I'm resizing it by XAML (circle crop):

<Ellipse x:Name="personImageContainer" Width="50" Height="50">
    <Ellipse.Fill>
        <ImageBrush x:Name="personImage" ImageSource="/Assets/BlankContact.png" Stretch="Uniform" />
    </Ellipse.Fill>
</Ellipse>

and just setting the image like this:

personImage.ImageSource = new BitmapImage(new Uri("http://lorempixel.com/500/500/"));

I can't seem to find any other settings in both ImageBrush and BitmapImage that does it.

like image 294
Dylan Briedis Avatar asked Feb 06 '23 21:02

Dylan Briedis


1 Answers

As an optimization, the framework will usually decode images at a smaller resolution to match the size of the target Image element displayed on screen, but this will only occur if the framework can determine straight away what the size of the target Image will be. If the framework cannot deduce this, then it will load the image at full resolution and be scaled down by the GPU instead which probably has shabby linear interpolation which makes images look gross when scaled down.

I think this is what's happening in your example because the ImageBrush doesn't know the size of the Ellipse it is applied to. (It's a custom way of displaying an image.)

Since you know the size of the Ellipse ahead of time, you can just tell the framework explicitly to decode the image at the resolution you specify.

<!-- Bad: image will be full resolution -->
<Ellipse Width="50" Height="50">
    <Ellipse.Fill>
        <ImageBrush Stretch="UniformToFill" ImageSource="Assets/Cat.jpg"/>
    </Ellipse.Fill>
</Ellipse>

<!-- Better: image is scaled down nicely and uses less memory -->
<Ellipse Width="50" Height="50">
    <Ellipse.Fill>
        <ImageBrush Stretch="UniformToFill">
            <ImageBrush.ImageSource>
                <BitmapImage UriSource="Assets/Cat.jpg" DecodePixelType="Logical" DecodePixelWidth="50"/>
            </ImageBrush.ImageSource>
        </ImageBrush>
    </Ellipse.Fill>
</Ellipse>

Screenshot

More information about this here.

like image 185
Decade Moon Avatar answered Feb 08 '23 11:02

Decade Moon