Мої зображення розмиті! Чому SnapsToDevicePixels WPF не працює?


165

Я використовую кілька зображень у програмі WPF.

XAML:

<Image Name="ImageOrderedList"
       Source="images/OrderedList.png"
       ToolTip="Ordered List"
       Margin="0,0,5,5"
       Width="20"
       Height="20"
       SnapsToDevicePixels="True"
       MouseUp="Image_MouseUp"
       MouseEnter="Image_MouseEnter"
       MouseLeave="Image_MouseLeave" />

Але, вони здаються нечіткими.

Чому ця SnapsToDevicePixels="True"лінія не запобігає цій проблемі?



4
Здається, ваші посилання на зображення порушені. Якщо у вас все ще є оригінальні зображення, будь ласка, перезавантажте їх у stack.imgur. Дякую.
Ільмарі Каронен

1
Якщо жодна з наведених нижче порад не працює негайно, також спробуйте змінити розмір зображення на коефіцієнт 4 в ширину та висоту. Тож замість 179 X 44 спробуйте 176 X 44.
Мартін Лоттерінг

Відповіді:


233

Ви можете розглянути можливість спробувати нову властивість, доступну зараз у WPF4 . Залиште RenderOptions.BitmapScalingModeна HighQuality або просто не оголосити.

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

У кореневому елементі (тобто у головному вікні) додайте це властивість: UseLayoutRounding="True" .

Властивість, доступна лише в Silverlight, тепер виправила всі бітові карти розмірів. :)


4
Більше інформації про цю нову власність можна знайти тут: blogs.msdn.com/text/archive/2009/08/27/layout-rounding.aspx
Домокун

5
UseLayoutRendering = "True" - це те, що я використовував - це ідеально підходить для вирішення моїх розмитих зображень. Дякую!
Метт Декре

25
ОКОНЧО !! UseLayoutRounding має бути встановлено за замовчуванням. Зображення відображаються так само, як оригінал і рівномірний текст у деяких місцях (як-от ContextMenus, як мінімум, для мене) виявляються чіткішими, ніж раніше. Дякую, Домокун!
грант

3
Я думаю, у тих, хто досі тримається на .NET 3.5 немає варіантів?
jpierson

2
Я виявляю, що це виправляє мою проблему, якщо я встановив властивість Stretch на None на зображеннях, але у всіх інших сценаріях, навіть якщо вимкнення та вивільнення зображень HighQuality вимкнено, розтягнення зображення все ще затримує WPF. Але, принаймні, це виправило проблему для не розтягнутих зображень (що в першу чергу не повинно було бути проблемою)
Крістіан Findlay

74

Замість того, щоб використовувати SnapsToDevicePixels, я натомість використовувавRenderOptions.BitmapScalingMode і вони тепер приємні і чіткі!

XAML:

<Image Name="ImageOrderedList"
       Source="images/OrderedList.png"
       ToolTip="Ordered List"
       Margin="0,0,5,5"
       Width="20"
       Height="20"
       RenderOptions.BitmapScalingMode="NearestNeighbor"
       MouseUp="Image_MouseUp"
       MouseEnter="Image_MouseEnter"
       MouseLeave="Image_MouseLeave" />

1
Крім того, якщо ваше зображення було точного розміру, як зазначено в тезі <Image>, воно не повинно масштабувати його, і воно повинно чітко відображатись.
Беардо

1
Я не впевнений, що це призведе до бажаного ефекту в інших DPI
Дейв,

1
Beardo, і вихідна графіка, і <Image> - це 20 пікселів на 20 пікселів. Наскільки я розумію, питання походить від WPF. Він начебто хоче знехтувати піксельну сітку монітора, тому логічна сітка зазвичай не ідеально поєднується з фізичною сіткою.
Зак Петерсон

9
@Zack Width = "20" не означає 20 пікселів. Це означає 20/96 дюйма. Якщо ваша ОС налаштована для роботи на 96 DPI, це 20 пікселів. Тепер, як ваш найближчий сусід виглядатиме на хорошому моніторі, наприклад, 160 DPI? А як це буде виглядати, коли ви друкуєте на 300 DPI? Ви не повинні оптимізувати свій розробник.
Френк Крюгер

2
Я також виявив, що для зображень розміром пікселів NevableNeighbor набагато кращий, ніж HighQuality, особливо якщо поєднувати його з img.Width = imgSource.PixelWidth; img.Height = imgSource.PixelHeight. Мій клієнт надав кілька зображень з різними шаленими значеннями DPI, і я не міг попросити клієнта перетворити їх усі, тому мені довелося використовувати цей злом.
JustAMartin

23

+1 для Зака ​​Петерсона

Я використовую .Net 3.5 sp1, і це виглядає як найпростіше рішення для великої кількості нечітких зображень. Вказувати RenderOptions на місці не складно, але для сторонніх компонентів стиль в ресурсі рівня додатків має сенс:

 <Style TargetType="{x:Type Image}">
    <Setter
        Property="RenderOptions.BitmapScalingMode"
        Value="NearestNeighbor" />
 </Style>

Працювало чудово, коли AvalonDock почав відображати розмиті значки.


1
AvalonDock так само мене болить ... і я все ще з. Net 3.5
Ignacio Soler Garcia

9

Використання в UseLayoutRounding="True"кореневому вікні працює у багатьох випадках, але у мене виникла проблема при використанні керування стрічкою WPF . Моє додаток використовує контекстні вкладки , які відображаються в відповідно до тим, що робить користувач , і коли я встановив UseLayoutRoundingуTrue вкладка контекстна не буде доступний широкому і іміджеві RibbonButton, ні інші . Також додаток замерзає на багато секунд і вентилятор процесора починає співати.

Використовуючи RenderOptions.BitmapScalingMode="NearestNeighbor"моє зображення, виправлено проблеми візуалізації зображення (нечіткі та обрізані зображення) та повністю сумісний із використанням контекстуальних вкладок стрічок.


1
UseLayoutRounding = "Істинно" працював для мене. Дякую. mikecroteau.wordpress.com/2013/01/20/wpf-net-xaml-blurry-images
mcroteau

6

RenderOptions.BitmapScalingMode = "Найближчий сусід" працює добре протягом більшої частини часу. Однак час від часу ви отримуєте графічні глюки (у моєму випадку 4 з 5 зображень виявлялися чудово, але на п'ятому спостерігалося незначне викривлення на правому краю). Я зафіксував це, збільшивши правий запас зображення зображення на 1.

Якщо це все-таки не виправить це, спробуйте керувати класом Bitmap вище, ніж згадує EugeneZ. Це заміна для управління зображенням, і поки що він працює досить добре для мене. Дивіться http://blogs.msdn.com/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx


5

Переконайтеся, що ви зберігаєте зображення в тому самому DPI, у якому працює ваша програма WPF, у деяких форматах зображень ця інформація зберігається як метадані. Я не знаю, чи це вирішує проблему, але я мав деякі проблеми через це, коли зображення розміром до 100% стали більшими або меншими, ніж очікувалося.

Може бути щось подібне.




3

Я виявив, що RenderOptions.BitmapScalingMode = "Найближчий сусід" не працює для мене. Я використовую Windows XP x32 з DirectX 9.0c. Оскільки власне візуалізація для WPF проводиться за допомогою DirectX, це може мати ефект. У мене ввімкнено антизбудження для XP із такими записами реєстру:

[HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Avalon.Graphics] "MaxMultisampleType" = dword: 00000004 "EnableDebugControl" = dword: 00000001

Однак вимкнення цих параметрів не впливає на зображення. Я думаю, що це впливає лише на 3D Viewports.

Нарешті я виявив, що розмиття відбувається як з текстом TextBlocks, так і з зображеннями. І розмиття відбувається лише для деяких текстових блоків та зображень, не для всіх.


3

Я виявив, що жодна комбінація запропонованих способів вирішення не дозволить вилікувати мою, здавалося б, випадкову проблему розмитого зображення. Мені подобається, що багато інших не можуть оновити до .net 4, щоб використовувати UseLayoutRenderingвластивість.

Що я знайшов працювати:

  • Переконайтеся, що ваші [оригінальні] розміри зображення кратні по 2. Це, здається, запобігає деяким проблемам масштабування зображення.
  • Іноді я також виявляв, що коригування поля на зображеннях пікселем або 2 може запобігти проблемі.

1

Перша моя думка, читаючи запитання, чи ти занадто сильно роздував зображення, але, схоже, це не так, коли дивишся на зображення у твоєму додатку.

Друга думка - палітра кольорів, але з чорним як одним із кольорів, який не відображається правильно, це не так імовірно.

Якщо ви можете повністю виключити два вищевикладені, я в даний час наткнувся.

В якості експерименту можна спробувати інші графічні формати, але PNG має бути добре. Мені доведеться продумати ще кілька, щоб придумати кращу відповідь.


1
+1, щоб уникнути необґрунтованих негативних голосів, оскільки, я думаю, ви запропонували кілька розумних пропозицій і намагалися лише допомогти, а головне, що з вашими пропозиціями не було нічого неправильного.
jpierson

1

Я намагався використовувати RenderOptions.BitmapScalingMode = HighQuality, схоже, викликає деякі проблеми в Windows 8.1, тому те, що я зробив, це запустити їх через інструмент під назвою PngOut.exe

http://advsys.net/ken/utils.htm

Це зменшує заголовок png, а також зменшує розмір, але не змінюючи якість зображення.

І тепер усі мої образи ідеальні! :-)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.