Ласкаво просимо до dev.net.ua Увійти | Приєднатися | Допомога

Решение проблемы с нечеткими растрами в WPF

Известно, что в текущей версии WPF существует проблема с качеством отображения растров. Возникает она из-за того, что WPF отображает визуальные элементы исходя из координат и размеров в логических единицах (долях дюйма) без точной привязки к пикселам. То есть, по умолчанию, растровое изображение в WPF-приложении будет иметь одинаковый размер в логических единицах на мониторе с разрешением 96 DPI и на супер-мониторе с разрешением 300 DPI. Теоретически это звучит хорошо, но на практике дело обстоит иначе.

Растровые изображения являются основным элементом пиксельной графики. Это означает, что эти избражения тесно связаны с пиксельной природой устройств, для использования на которых они предназначены. Точно также, как игра в «морской бой» связана с клетками на тетрадном листе. Таким образом, если начать играть в независимость пиксельных изображений от собственно пикселей, мы получим размытую картинку на мониторе. Что мы и имеем в современных WPF-приложениях.

На самом деле, есть случаи, когда такое положение вещей допустимо. Например, растянутая на фоне элемента управления текстура с размытыми цветами, и тому подобное. Но в большинстве случаев, когда растры используются для картинок в кнопках на панелях управления, меню (16х16, 32х32 пикселя), и так далее, это не годится; картинки размыты, приложение неумолимо теряет профессиональный вид.

Это не устраивает многих разработчиков, и обсуждение этой темы обычно заканчивается бессильными протестами в сторону создателей платформы. Но, к счастью, MSDN-блоггером было предложено решение этой проблемы. В статье описывается класс Bitmap, который позволяет отображать растры с точной пиксельной привязкой к целевому устройству. Используйте этот класс, и ваши растры будут вылядеть как родные! При этом, естественно на супер-мниторе с 300 DPI ваша картинка будет выглядеть крошечной. Но на то они и растры, я считаю. Примяняйте векторные изображения, и с масштабированием все будет отлично.

Прекрасно, но существует проблема, которая не позволяет использовать этот класс в случаях, когда нужно осущеcтвить привязку к данным через DataContext. Я столкнулся с этим при написании CellTemplate для ListView. Предполагалось, что ячейка будет содержать растровое избражение, привязанное к пикселам.

Но это, к сожалению, не работало. Возникало исключение, смысл которого в том, что наследование DataContext работает только для классов, производных от FrameworkElement. В то же время, наш американский товарищ унаследовал свой класс Bitmap от UIElement, потому что только так можно перекрыть методы, которые являются sealed для наследников FrameworkElement.

Использовать класс очень хотелось, и мне пришлось сделать обертку вокруг Bitmap, порожденную от FrameworkElement. Для того, чтобы это выглядело прозрачно, я перекрыл визуальное дерево элемента и встроил в него реализацию, выполненную ранее. Моя обертка тоже называется Bitmap, а внутренний класс, который выполняет собственно привязку к пикселам, я переименовал в BitmapUIElement.

Чтобы проиллюстрировать все это, я сделал небольшой пример. В нем используется ListView для отображения всех файлов из папки System32 – имена и иконки 32х32. Обратите внимание, что иконки выглядят так же качественно, как в Explorer.

Вот, собственно, и все. В заключение еще раз скажу, что если у вас есть возможность использовать векторные изображения, то лучше используйте их.

Опубліковані Sunday, February 03, 2008 3:47 PM від EugeneZ

Коментарі

# re: Решение проблемы с нечеткими растрами в WPF

Дякую за лінк на пост.

Monday, February 04, 2008 12:38 PM by Eugene Fotin

# re: Решение проблемы с нечеткими растрами в WPF

Нема за що )

Tuesday, February 05, 2008 5:26 AM by EugeneZ
Анонімні коментарі деактивовані. Увійдіть або Зареєструйтесь щоб мати доступ до ресурсів Спільноти.