Mes images sont floues! Pourquoi les SnapsToDevicePixels de WPF ne fonctionnent-ils pas?

165

J'utilise des images dans mon applcation 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" />

Mais, ils semblent flous.

Pourquoi cette SnapsToDevicePixels="True"ligne n'empêche- t-elle pas ce problème?

Zack Peterson
la source
4
Vos liens d'image semblent s'être rompus. Si vous avez toujours les images originales, veuillez les télécharger à nouveau dans stack.imgur. Merci.
Ilmari Karonen
1
Si aucun des conseils ci-dessous ne fonctionne immédiatement, essayez également de modifier la taille de votre image par un facteur de 4 en largeur et en hauteur. Alors au lieu de 179 X 44, essayez 176 X 44.
Martin Lottering

Réponses:

233

Vous voudrez peut-être envisager d'essayer une nouvelle propriété disponible maintenant dans WPF4 . Laissez le RenderOptions.BitmapScalingModeà HighQuality ou ne le déclarez tout simplement pas.

NearestNequart a fonctionné pour moi, sauf que cela a conduit à des bitmaps irréguliers lors du zoom sur l'application. Cela ne semblait pas non plus résoudre les problèmes de taille des icônes de manière étrange.

Sur votre élément racine (votre fenêtre principale) ajouter cette propriété: UseLayoutRounding="True".

Une propriété auparavant disponible uniquement dans Silverlight a maintenant résolu tous les problèmes de dimensionnement Bitmap. :)

Domokun
la source
4
Plus d'informations sur cette nouvelle propriété ici: blogs.msdn.com/text/archive/2009/08/27/layout-rounding.aspx
Domokun
5
UseLayoutRendering = "True" est ce que j'ai utilisé - c'est parfait pour résoudre mes images floues. Merci!
Matt DeKrey du
25
ENFIN!! UseLayoutRounding doit être défini par défaut. Les images apparaissent comme l'original et même le texte à certains endroits (comme ContextMenus, du moins pour moi) apparaît plus net qu'auparavant. Merci, Domokun!
accorder le
3
Je suppose que ceux d'entre nous qui sont toujours bloqués sur .NET 3.5 n'ont pas d'options?
jpierson
2
Je trouve que cela résout mon problème si je définis la propriété Stretch sur Aucun sur les images, mais dans tous les autres scénarios, même avec le rendu d'image HighQuality et l'alias désactivés, l'étirement d'image est toujours nul dans WPF. Mais au moins, cela a résolu le problème des images non étirées (ce qui n'aurait pas dû être un problème en premier lieu)
Christian Findlay
74

Plutôt que d'utiliser SnapsToDevicePixels, j'ai plutôt utilisé RenderOptions.BitmapScalingModeet ils sont maintenant beaux et nets!

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" />
Zack Peterson
la source
1
De plus, si votre image avait la taille exacte spécifiée dans la balise <Image>, elle n'aurait pas besoin de la mettre à l'échelle et devrait la rendre nette.
Beardo
1
Je ne suis pas sûr que cela aura l'effet souhaité à un DPI différent
Dave
1
Beardo, le graphique source et l '<Image> mesurent tous deux 20 pixels sur 20 pixels. Si je comprends bien, le problème vient de WPF. Il veut en quelque sorte ignorer la grille de pixels du moniteur, donc sa grille logique ne s'alignera généralement pas parfaitement avec la grille physique.
Zack Peterson
9
@Zack Width = "20" ne signifie pas 20 pixels. Cela signifie 20/96 de pouce. Si votre système d'exploitation est configuré pour fonctionner à 96 PPP, il est de 20 pixels. Maintenant, à quoi ressemblera votre voisin le plus proche sur un bon moniteur, 160 DPI par exemple? Et à quoi cela ressemblera-t-il lorsque vous imprimerez à 300 DPI? Vous ne devriez pas optimiser pour votre machine de développement.
Frank Krueger
2
J'ai également trouvé que pour les images de taille pixel, NearestNeighbors est bien meilleur que HighQuality, surtout si vous le combinez avec img.Width = imgSource.PixelWidth; img.Height = imgSource.PixelHeight. Mon client a fourni des images avec différentes valeurs de DPI folles et je ne pouvais pas demander au client de toutes les convertir, j'ai donc dû utiliser ce hack.
JustAMartin
23

+1 pour Zack Peterson

J'utilise .Net 3.5 sp1 et cela ressemble à la solution la plus simple pour un grand nombre d'images floues. Ce n'est pas un gros problème de spécifier RenderOptions sur place, mais pour les composants tiers, un style dans une ressource au niveau de l'application a du sens:

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

A bien fonctionné quand AvalonDock a commencé à rendre des icônes floues.

DK.
la source
1
AvalonDock me donne également les mêmes maux de tête ... et je suis toujours avec .Net 3.5
Ignacio Soler Garcia
9

L'utilisation UseLayoutRounding="True"de la fenêtre à la racine fonctionne dans de nombreux cas, mais j'ai rencontré un problème lors de l'utilisation du contrôle du ruban WPF . Mon application repose sur des onglets contextuels qui apparaissent en fonction de ce que fait l'utilisateur et lorsque je définis le UseLayoutRoundingsur True, l'onglet contextuel n'apparaît pas et l'image du RibbonButton non plus. En outre, l'application se fige pendant plusieurs secondes et le ventilateur du processeur commence à chanter.

L'utilisation RenderOptions.BitmapScalingMode="NearestNeighbor"sur mon image a corrigé les problèmes de rendu de l'image (image floue et recadrée) et est entièrement compatible avec l'utilisation des onglets contextuels du ruban.

Omid B.
la source
1
UseLayoutRounding = "True" a fonctionné pour moi. Merci. mikecroteau.wordpress.com/2013/01/20/wpf-net-xaml-blurry-images
mcroteau
6

RenderOptions.BitmapScalingMode = "NearestNeighbors" fonctionne bien la plupart du temps. Cependant, vous aurez parfois des problèmes graphiques (dans mon cas, 4 images sur 5 se sont bien présentées, mais la cinquième avait une légère distorsion sur le bord droit). Je l'ai corrigé en augmentant la marge droite du contrôle Image de 1.

Si cela ne résout toujours pas le problème, essayez le contrôle de classe Bitmap ci-dessus mentionné par EugeneZ. C'est un remplacement du contrôle Image et jusqu'à présent, cela a plutôt bien fonctionné pour moi. Voir http://blogs.msdn.com/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx


la source
5

Assurez-vous que vous enregistrez l'image dans le même DPI que votre application WPF fonctionne, certains formats d'image ont ces informations stockées sous forme de métadonnées. Je ne sais pas si cela résout le problème mais j'ai quelques problèmes à cause de cela où les images redimensionnées à 100% sont devenues plus grandes ou plus petites que prévu.

Peut-être quelque chose de similaire.


la source
5

use UseLayoutRounding = True pour l'élément le plus haut de votre application

Varatharaj
la source
3

J'ai trouvé que le RenderOptions.BitmapScalingMode = "NearestNeighbors" ne fonctionne pas pour moi. J'utilise Windows XP x32 avec DirectX 9.0c. Comme le rendu réel pour WPF est effectué avec DirectX, cela peut avoir un effet. L'anti-aliasing est activé pour XP avec les entrées de registre suivantes:

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

Cependant, désactiver aa avec ces paramètres n'a aucun effet sur les images. Je pense que cela affecte uniquement les fenêtres 3D.

Enfin, j'ai trouvé que le flou se produit avec le texte de TextBlocks ainsi qu'avec les images. Et le flou ne se produit que pour certains blocs de texte et images, pas tous.

anon
la source
3

J'ai trouvé qu'aucune combinaison des solutions de contournement suggérées ne résoudrait mon problème d'image floue apparemment aléatoire. J'aime beaucoup d'autres ne peuvent pas passer à .net 4 afin d'utiliser la UseLayoutRenderingpropriété.

Ce que j'ai trouvé pour fonctionner:

  • Assurez-vous que les dimensions de votre image [d'origine] sont des multiples de 2. Cela semble éviter certains des problèmes de mise à l'échelle de l'image.
  • Parfois, j'ai également constaté que l'ajustement des marges sur les images par un pixel ou 2 peut éviter le problème.
Jahhai
la source
1

Ma première pensée, en lisant la question, était que vous faisiez trop exploser l'image, mais cela ne semble pas être le cas en regardant l'image que vous avez de l'application.

La deuxième pensée est la palette de couleurs, mais avec le noir comme l'une des couleurs qui ne sont pas rendues correctement, ce n'est pas aussi probable.

Si vous pouvez complètement exclure les deux ci-dessus, je suis actuellement perplexe.

À titre expérimental, vous pouvez essayer d'autres formats graphiques, mais PNG devrait convenir. Je vais devoir réfléchir davantage pour trouver une meilleure réponse.

Gregory A Beamer
la source
1
+1 pour éviter les votes négatifs injustifiés, car je pense que vous avez proposé des suggestions raisonnables et que vous avez seulement essayé d'aider et, plus important encore, il n'y avait rien d'incorrect dans vos suggestions.
jpierson
1

J'ai essayé d'utiliser RenderOptions.BitmapScalingMode = HighQuality, semble causer des problèmes dans Windows 8.1, alors ce que j'ai fait, c'est de les exécuter via l'outil appelé PngOut.exe

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

Ce qui réduit l'en-tête du png, et réduit également la taille, mais sans changer la qualité de l'image.

Et maintenant toutes mes images sont parfaites! :-)

MMM
la source