Размытые изображения WPF

Я ищу способ предотвратить размытие изображений в WPF. Я хочу, чтобы мое приложение выглядело хорошо на дисплеях с высоким разрешением, поэтому я создал значки в 96x96px для отображения размером 32x32.

Там много в google, чтобы найти, и даже в stackoverflow есть несколько тем об этом. Подводя итог, говорят: Включите свойство UseLayoutRounding и установите RenderOptions.BitmapScalingMode на HighQuality. К сожалению, это не работает для меня - изображения все еще выглядят очень размытыми. Затем я протестировал свое приложение на ноутбуке с более высоким DPI aaaand - WOW. Изображения полностью острые и приятные.

Моим единственным решением было создание настраиваемого элемента управления, который преобразует ImageSource в System.Drawing.Bitmap, перетаскивает его там, чтобы соответствовать размеру изображения и преобразовывать его обратно в WPF ImageSource. Очевидно, это не идеальное решение!

Example on low-DPI display (96dpi)Example on high-DPI display (~122dpi)

Итак, встает вопрос: почему мои изображения размыты на дисплее с низким разрешением? Я не знаю, что может вызвать это, и надеюсь, что у кого-то есть идея исправить это.

Вот некоторые из наиболее полезных ресурсов, которые я нашел:

EDIT:

В соответствии с запрошенным здесь кодом для преобразования ImageSource. Есть несколько методов-вызовов, которые не включены, но вы можете быстро найти их через google.

// Calculate the conversion factor.
float dpi = WpfImageHelper.GetCurrentDPI(this);
float factor = dpi / 96f;
int width = (int)Math.Round(this.image.ActualWidth * factor);
int height = (int)Math.Round(this.image.ActualHeight * factor);

// Create bitmaps.
Bitmap oldBitmap = WpfImageHelper.ToWinFormsBitmap2((BitmapSource)this.Source);
Bitmap newBitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

// Draw the new bitmap. Use high-quality interpolation mode.
using (Graphics g = Graphics.FromImage(newBitmap))
{
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;

    g.Clear(System.Drawing.Color.Transparent);
    g.DrawImage(oldBitmap, 0, 0, newBitmap.Width, newBitmap.Height);
}

// Set the image source to the resized bitmap.
this.Source = WpfImageHelper.ToWpfBitmap2(newBitmap); 

Ответ 1

Ваши значки - это растровые изображения, поэтому вы не собираетесь решать эту проблему IMHO. Вам нужно посмотреть на другое решение. Вы хотите, чтобы ваши значки были независимыми от устройства, поэтому вам нужно либо преобразовать изображения в векторы, либо конвертировать изображения в xaml. Этот вопрос задавали и отвечали раньше, и решение не требует больших усилий.

create-vector-from-image

convert-svg-to-xaml

Ответ 2

Согласно этот пост (от уважаемого создателя VirtualDub), высококачественный метод "Фан" WPF на самом деле не такой замечательный, Ваш пользовательский контроль использует превосходный бикубический метод.

Тема передискретизации идет довольно глубоко; см. ссылки в Old Pro ответ на вопрос о качестве масштабирования, особенно этот.