Сглаживание растровых изображений в UWP

#c# #xaml #uwp

#c# #xaml #uwp

Вопрос:

Я пытаюсь выяснить, как изменить размер изображения без потери качества в UWP. Я знаю, что в WPF есть возможность сгладить изображение с помощью этого: RenderOptions.BitmapScalingMode="HighQuality" но, похоже, я не могу найти эквивалент в UWP.

Вот как выглядит изображение:

И на что это должно быть похоже:

Если присмотреться, то можно увидеть, что картинка сильно неровная. Как я могу добиться этого в UWP?

Я изменяю его размер с помощью XAML (обрезка по кругу):

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

и просто устанавливаем изображение следующим образом:

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

Кажется, я не могу найти никаких других настроек в обоих, ImageBrush и BitmapImage это делает.

Комментарии:

1. Не используйте фильтр точечной выборки при изменении размера изображения. Вместо этого используйте билинейную фильтрацию или какой-либо другой фильтр, если этого недостаточно. Кроме того, если вам нужна помощь с кодом, обычно полезно опубликовать этот код. Где ваш код изменения размера?

2. Я не использую какие-либо методы фильтрации изменения размера, я хочу посмотреть, есть ли способ сделать это в XAML.

3. каков размер исходного изображения?

4. Изображения, которые у меня есть, разного размера.

Ответ №1:

В качестве оптимизации фреймворк обычно декодирует изображения с меньшим разрешением, чтобы соответствовать размеру целевого Image элемента, отображаемого на экране, но это произойдет только в том случае, если фреймворк может сразу определить, каким будет размер целевого Image элемента. Если фреймворк не может вывести это, то он загрузит изображение с полным разрешением и вместо этого уменьшит его с помощью графического процессора, который, вероятно, имеет плохую линейную интерполяцию, из-за чего изображения выглядят грубыми при уменьшении.

Я думаю, что это то, что происходит в вашем примере, потому что ImageBrush не знает размер Ellipse , к которому он применяется. (Это пользовательский способ отображения изображения.)

Поскольку вы заранее знаете размер Ellipse , вы можете просто явно указать платформе декодировать изображение с указанным вами разрешением.

 <!-- 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>
  

Скриншот

Более подробная информация об этом здесь.

Комментарии:

1. Хотя это улучшает качество изображения, оно все еще не позволяет вам выбрать режим интерполяции. Вам нужно было бы установить ImageSource во время выполнения, используя BitmapEncoder для создания изображения с измененным размером. Это позволяет вам специально задать BitmapTransform. Режим интерполяции .

2. Спасибо! Теперь картинки выглядят намного лучше!:)

3. Знаете ли вы, как выполнить нечто подобное с элементом BitmapIcon?