Meine Bilder sind verschwommen! Warum funktionieren die SnapsToDevicePixels von WPF nicht?

165

Ich verwende einige Bilder in meiner WPF-Anwendung.

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" />

Aber sie erscheinen verschwommen.

Warum SnapsToDevicePixels="True"verhindert diese Linie dieses Problem nicht?

Zack Peterson
quelle
4
Ihre Bildlinks scheinen defekt zu sein. Wenn Sie noch die Originalbilder haben, laden Sie diese bitte erneut auf stack.imgur hoch. Vielen Dank.
Ilmari Karonen
1
Wenn keiner der folgenden Tipps sofort funktioniert, versuchen Sie auch, die Größe Ihres Bildes in Breite und Höhe auf den Faktor 4 zu ändern. Versuchen Sie also statt 179 x 44 176 x 44.
Martin Lottering

Antworten:

233

Möglicherweise möchten Sie eine neue Eigenschaft ausprobieren, die jetzt in WPF4 verfügbar ist . Lassen Sie das RenderOptions.BitmapScalingModezu Highquality oder es einfach nicht erklären.

NearestNeighbor arbeitete für mich, außer dass es beim Vergrößern der Anwendung zu zackigen Bitmaps kam. Es schien auch keine Störungen zu beheben, bei denen die Größe der Symbole auf seltsame Weise gemessen wurde.

Fügen Sie in Ihrem Stammelement (dh in Ihrem Hauptfenster) diese Eigenschaft hinzu : UseLayoutRounding="True".

Eine Eigenschaft, die bisher nur in Silverlight verfügbar war, hat jetzt alle Probleme mit der Bitmap-Größe behoben. :) :)

Domokun
quelle
4
Weitere Informationen zu dieser neuen Immobilie finden Sie hier: blogs.msdn.com/text/archive/2009/08/27/layout-rounding.aspx
Domokun
5
UseLayoutRendering = "True" habe ich verwendet - dies ist perfekt zum Lösen meiner verschwommenen Bilder. Vielen Dank!
Matt DeKrey
25
ENDLICH!! UseLayoutRounding sollte standardmäßig festgelegt sein. Bilder werden genauso wie das Original und an einigen Stellen sogar Text angezeigt (wie zumindest für mich ContextMenus) und schärfer als zuvor. Danke, Domokun!
gewähren
3
Ich denke, diejenigen von uns, die noch auf .NET 3.5 stecken, haben keine Optionen?
Jpierson
2
Ich stelle fest, dass dies mein Problem behebt, wenn ich die Eigenschaft "Strecken" für Bilder auf "Keine" setze. In allen anderen Szenarien ist die Bilddehnung in WPF jedoch immer noch schlecht, selbst wenn das Rendern und Aliasing von HighQuality-Bildern deaktiviert ist. Aber zumindest hat dies das Problem für nicht gestreckte Bilder behoben (was eigentlich kein Problem sein sollte)
Christian Findlay
74

Anstatt zu verwenden SnapsToDevicePixels, habe ich stattdessen verwendet RenderOptions.BitmapScalingModeund sie sind jetzt schön und knackig!

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
quelle
1
Auch wenn Ihr Bild genau die Größe hat, die im <Image> -Tag angegeben ist, muss es nicht skaliert werden und sollte es gestochen scharf wiedergeben.
Beardo
1
Ich bin nicht sicher, ob dies bei einem anderen DPI den gewünschten Effekt haben wird
Dave
1
Beardo, sowohl die Quellgrafik als auch das <Bild> sind beide 20 x 20 Pixel groß. Soweit ich weiß, kommt das Problem von WPF. Es möchte das Pixelraster des Monitors irgendwie ignorieren, so dass das logische Raster normalerweise nicht perfekt mit dem physischen Raster übereinstimmt.
Zack Peterson
9
@Zack Width = "20" bedeutet nicht 20 Pixel. Es bedeutet 20/96 Zoll. Wenn Ihr Betriebssystem für 96 DPI konfiguriert ist, sind es 20 Pixel. Wie sieht Ihr nächster Nachbar auf einem guten Monitor aus, zum Beispiel 160 DPI? Und wie sieht es aus, wenn Sie mit 300 DPI drucken? Sie sollten nicht für Ihre Entwicklungsmaschine optimieren.
Frank Krueger
2
Ich habe auch festgestellt, dass NearestNeighbor für Bilder in Pixelgröße viel besser ist als HighQuality, insbesondere wenn Sie es mit img.Width = imgSource.PixelWidth kombinieren. img.Height = imgSource.PixelHeight. Mein Client hat einige Bilder mit unterschiedlichen verrückten DPI-Werten bereitgestellt, und ich konnte den Client nicht bitten, sie alle zu konvertieren. Daher musste ich diesen Hack verwenden.
JustAMartin
23

+1 für Zack Peterson

Ich verwende .Net 3.5 sp1 und es scheint die einfachste Lösung für eine große Anzahl von Fuzzy-Bildern zu sein. Es ist keine große Sache, RenderOptions direkt anzugeben, aber für Komponenten von Drittanbietern ist ein Stil in Ressourcen auf App-Ebene sinnvoll:

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

Funktionierte gut, als AvalonDock anfing, verschwommene Symbole zu rendern.

DK.
quelle
1
AvalonDock bereitet mir auch die gleichen Kopfschmerzen ... und ich bin immer noch bei .Net 3.5
Ignacio Soler Garcia
9

Die Verwendung des UseLayoutRounding="True"Fensters im Stammverzeichnis funktioniert in vielen Fällen, bei der Verwendung des WPF-Multifunktionsleisten- Steuerelements ist jedoch ein Problem aufgetreten . Meine Anwendung basiert UseLayoutRoundingauf Truekontextbezogenen Registerkarten, die entsprechend den Aktivitäten des Benutzers angezeigt werden. Wenn ich die Option auf einstelle , wird die kontextbezogene Registerkarte nicht angezeigt und das Bild des RibbonButton auch nicht. Außerdem friert die Anwendung für viele Sekunden ein und der CPU-Lüfter beginnt zu singen.

Die Verwendung RenderOptions.BitmapScalingMode="NearestNeighbor"auf meinem Bild hat die Probleme beim Rendern von Bildern (unscharfes und zugeschnittenes Bild) behoben und ist vollständig kompatibel mit der Verwendung der kontextbezogenen Registerkarten für Multifunktionsleisten.

Omid B.
quelle
1
UseLayoutRounding = "True" hat bei mir funktioniert. Vielen Dank. mikecroteau.wordpress.com/2013/01/20/wpf-net-xaml-blurry-images
mcroteau
6

RenderOptions.BitmapScalingMode = "NearestNeighbor" funktioniert die meiste Zeit gut. Gelegentlich treten jedoch grafische Störungen auf (in meinem Fall wurden 4 von 5 Bildern gut angezeigt, aber das fünfte hatte eine leichte Verzerrung am rechten Rand). Ich habe es behoben, indem ich den rechten Rand des Bildsteuerelements um 1 vergrößert habe.

Wenn dies immer noch nicht behoben werden kann, versuchen Sie es mit dem Bitmap-Klassensteuerelement oben, das EugeneZ erwähnt. Es ist ein Ersatz für die Bildsteuerung und bisher hat es für mich ziemlich gut funktioniert. Siehe http://blogs.msdn.com/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx


quelle
5

Stellen Sie sicher, dass Sie das Bild in derselben DPI speichern, in der Ihre WPF-Anwendung arbeitet. In einigen Bildformaten werden diese Informationen als Metadaten gespeichert. Ich weiß nicht, ob dies das Problem löst, aber ich habe einige Probleme, weil Bilder, deren Größe auf 100% geändert wurde, größer oder kleiner als erwartet wurden.

Könnte etwas Ähnliches sein.


quelle
5

Verwenden Sie UseLayoutRounding = True für das oberste Element in Ihrer Anwendung

Varatharaj
quelle
3

Ich habe festgestellt, dass RenderOptions.BitmapScalingMode = "NearestNeighbor" für mich nicht funktioniert. Ich verwende Windows XP x32 mit DirectX 9.0c. Da das eigentliche Rendern für WPF mit DirectX erfolgt, kann dies Auswirkungen haben. Ich habe Anti-Aliasing für XP mit den folgenden Registrierungseinträgen aktiviert:

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

Das Deaktivieren von aa mit diesen Einstellungen hat jedoch keine Auswirkungen auf die Bilder. Ich denke, dies wirkt sich nur auf 3D-Ansichtsfenster aus.

Schließlich stellte ich fest, dass die Unschärfe sowohl beim Text von TextBlocks als auch bei Bildern auftritt. Und die Unschärfe tritt nur bei einigen Textblöcken und Bildern auf, nicht bei allen.

anon
quelle
3

Ich habe festgestellt, dass keine Kombination der vorgeschlagenen Problemumgehungen mein scheinbar zufälliges Problem mit verschwommenen Bildern beheben würde. Ich mag viele andere, die nicht auf .net 4 upgraden können, um die UseLayoutRenderingEigenschaft zu nutzen .

Was ich gefunden habe, um zu arbeiten:

  • Stellen Sie sicher, dass Ihre [ursprünglichen] Bildabmessungen ein Vielfaches von 2 sind. Dies scheint einige der Probleme mit der unkonventionellen Bildskalierung zu vermeiden.
  • Manchmal habe ich auch festgestellt, dass das Anpassen der Ränder von Bildern um ein oder zwei Pixel das Problem verhindern kann.
Jahhai
quelle
1

Mein erster Gedanke beim Lesen der Frage war, dass Sie das Bild zu stark in die Luft gesprengt haben, aber das scheint bei dem Bild, das Sie von der App haben, nicht der Fall zu sein.

Der zweite Gedanke ist die Farbpalette, aber mit Schwarz als einer der Farben, die nicht richtig gerendert werden, ist dies nicht so wahrscheinlich.

Wenn Sie die beiden oben genannten vollständig ausschließen können, bin ich derzeit ratlos.

Als Experiment können Sie andere Grafikformate ausprobieren, aber PNG sollte in Ordnung sein. Ich muss noch etwas darüber nachdenken, um eine bessere Antwort zu finden.

Gregory A Beamer
quelle
1
+1, um ungerechtfertigte negative Stimmen abzuwehren, da ich denke, Sie haben einige vernünftige Vorschläge gemacht und nur versucht zu helfen, und vor allem waren Ihre Vorschläge nicht falsch.
Jpierson
1

Ich habe versucht, RenderOptions.BitmapScalingMode = HighQuality zu verwenden. Es scheint, dass dies einige Probleme in Windows 8.1 verursacht. Ich habe sie also über das Tool PngOut.exe ausgeführt

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

Dies reduziert den Header des PNG und reduziert auch die Größe, ohne jedoch die Bildqualität zu ändern.

Und jetzt sind alle meine Bilder perfekt! :-)

MMM
quelle