Le mie immagini sono sfocate! Perché gli SnapsToDevicePixels di WPF non funzionano?


165

Sto usando alcune immagini nella mia applicazione 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" />

Ma sembrano sfocati.

Perché quella SnapsToDevicePixels="True"linea non impedisce questo problema?



4
I collegamenti alle tue immagini sembrano essersi interrotti. Se hai ancora le immagini originali, ti preghiamo di ricaricarle su stack.imgur. Grazie.
Ilmari Karonen,

1
Se nessuno dei seguenti suggerimenti funziona immediatamente, prova anche a modificare le dimensioni dell'immagine con un fattore 4 in larghezza e altezza. Quindi, invece di 179 X 44, prova 176 X 44.
Martin Lottering

Risposte:


233

Puoi provare a provare una nuova proprietà disponibile ora in WPF4 . Lascia RenderOptions.BitmapScalingModea HighQuality o semplicemente non dichiararlo.

Il vicino più vicino ha funzionato per me tranne che ha portato a bitmap jaggy durante lo zoom sull'applicazione. Inoltre, non sembrava correggere alcun problema tecnico in cui le icone venivano ridimensionate in modi strani.

Sul vostro elemento radice (cioè la finestra principale) Aggiungi questa proprietà: UseLayoutRounding="True".

Una proprietà precedentemente disponibile solo in Silverlight ora ha risolto tutti i problemi di dimensionamento di Bitmap. :)


4
Maggiori informazioni su questa nuova proprietà sono disponibili qui: blogs.msdn.com/text/archive/2009/08/27/layout-rounding.aspx
Domokun

5
UseLayoutRendering = "True" è quello che ho usato - questo è perfetto per risolvere le mie immagini sfocate. Grazie!
Matt DeKrey,

25
FINALMENTE!! UseLayoutRounding dovrebbe essere impostato per impostazione predefinita. Le immagini vengono visualizzate proprio come il testo originale e persino in alcuni punti (almeno come ContextMenus, almeno per me). Grazie Domokun!
concedi il

3
Immagino che quelli di noi ancora bloccati su .NET 3.5 non abbiano opzioni?
jpierson,

2
Sto scoprendo che questo risolve il mio problema se imposto la proprietà Stretch su None sulle immagini, ma in tutti gli altri scenari, anche con il rendering e l'aliasing delle immagini HighQuality disattivati, lo stiramento delle immagini fa ancora schifo in WPF. Ma almeno questo ha risolto il problema delle immagini non allungate (che non avrebbero dovuto essere un problema in primo luogo)
Christian Findlay,

74

Invece di usare SnapsToDevicePixels, ho usato invece RenderOptions.BitmapScalingModee ora sono belli e nitidi!

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
Inoltre, se l'immagine avesse le dimensioni esatte come specificato nel tag <Image>, non avrebbe dovuto ridimensionarla e renderla nitida.
Beardo,

1
Non sono sicuro che ciò avrà l'effetto desiderato con un DPI diverso
Dave,

1
Beardo, sia l'immagine sorgente che <Image> sono entrambi 20 pixel per 20 pixel. A quanto ho capito, il problema proviene da WPF. In un certo senso vuole ignorare la griglia di pixel del monitor, quindi la sua griglia logica di solito non si allinea perfettamente con la griglia fisica.
Zack Peterson,

9
@Zack Width = "20" non significa 20 pixel. Significa 20/96 di pollice. Se il tuo sistema operativo è configurato per funzionare a 96 DPI, allora è di 20 pixel. Ora come apparirà il tuo vicino più vicino su un buon monitor, ad esempio 160 DPI? E come apparirà quando si stampa a 300 DPI? Non dovresti ottimizzare per la tua macchina di sviluppo.
Frank Krueger,

2
Ho anche scoperto che per le immagini in formato pixel il valore più vicino è molto meglio di HighQuality, soprattutto se lo si combina con img.Width = imgSource.PixelWidth; img.Height = imgSource.PixelHeight. Il mio cliente ha fornito alcune immagini con diversi valori DPI folli e non ho potuto chiedere al cliente di convertirle tutte, quindi ho dovuto usare questo hack.
JustAMartin,

23

+1 per Zack Peterson

Sto usando .Net 3.5 sp1 e sembra la soluzione più semplice per un gran numero di immagini fuzzy. Non è un grosso problema specificare RenderOptions sul posto, ma per i componenti di terze parti ha senso uno stile nelle risorse a livello di app:

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

Ha funzionato bene quando AvalonDock ha iniziato a rendere icone sfocate.


1
Anche AvalonDock mi dà gli stessi mal di testa ... e sono ancora con .Net 3.5
Ignacio Soler Garcia

9

L'uso della UseLayoutRounding="True"finestra di root funziona in molti casi, ma ho riscontrato un problema durante l'utilizzo del controllo Ribbon WPF . La mia applicazione si basa su schede contestuali che appaiono in base a ciò che l'utente sta facendo e quando imposto il UseLayoutRoundingto True, la scheda contestuale non viene visualizzata e nemmeno l'immagine di RibbonButton. Inoltre, l'applicazione si blocca per molti secondi e la ventola della CPU inizia a cantare.

L'utilizzo RenderOptions.BitmapScalingMode="NearestNeighbor"sulla mia immagine ha corretto i problemi di rendering dell'immagine (immagine sfocata e ritagliata) ed è pienamente compatibile con l'utilizzo delle schede contestuali della barra multifunzione.


1
UseLayoutRounding = "True" ha funzionato per me. Grazie. mikecroteau.wordpress.com/2013/01/20/wpf-net-xaml-blurry-images
mcroteau

6

RenderOptions.BitmapScalingMode = "Il più vicino" funziona bene per la maggior parte del tempo. Tuttavia, a volte otterrai anomalie grafiche (nel mio caso, 4 immagini su 5 sono apparse bene, ma la quinta ha una leggera distorsione sul bordo destro). Ho risolto il problema aumentando di 1 il margine destro del controllo immagine.

Se il problema persiste, prova il controllo della classe Bitmap sopra menzionato da EugeneZ. È un sostituto del controllo Image e finora ha funzionato abbastanza bene per me. Vedi http://blogs.msdn.com/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx


5

Assicurati di salvare l'immagine nello stesso DPI in cui l'applicazione WPF sta funzionando, in alcuni formati di immagine queste informazioni sono memorizzate come metadati. Non so se questo risolva il problema, ma ho avuto alcuni problemi a causa di ciò in cui le immagini ridimensionate al 100% sono diventate più grandi o più piccole del previsto.

Potrebbe essere qualcosa di simile.


5

use UseLayoutRounding = True fino all'elemento più in alto nella tua applicazione



3

Ho scoperto che RenderOptions.BitmapScalingMode = "Il più vicino" non funziona per me. Sto usando Windows XP x32 con DirectX 9.0c. Poiché il rendering effettivo per WPF viene eseguito con DirectX, ciò potrebbe avere un effetto. Ho attivato l'antialiasing per XP con le seguenti voci di registro:

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

Tuttavia, la disattivazione di aa con queste impostazioni non ha alcun effetto sulle immagini. Penso che questo abbia effetto solo sulle finestre 3D.

Infine, ho scoperto che la sfocatura si verifica con il testo di TextBlocks e con le immagini. E la sfocatura si verifica solo per alcuni blocchi di testo e immagini, non tutti.


3

Ho scoperto che nessuna combinazione delle soluzioni alternative suggerite potrebbe curare il mio problema di immagine sfocata apparentemente casuale. Mi piace che molti altri non possano eseguire l'aggiornamento a .net 4 per utilizzare la UseLayoutRenderingproprietà.

Cosa ho scoperto di funzionare:

  • Assicurati che le dimensioni dell'immagine [originale] siano multipli di 2. Questo sembra impedire alcuni dei funky problemi di ridimensionamento delle immagini.
  • A volte ho anche scoperto che la regolazione dei margini sulle immagini di un pixel o 2 può prevenire il problema.

1

Il mio primo pensiero, leggendo la domanda, è che stavi facendo esplodere troppo l'immagine, ma non sembra essere il caso di guardare l'immagine che hai dell'app.

Il secondo pensiero è la tavolozza dei colori, ma con il nero come uno dei colori che non viene visualizzato correttamente, questo non è altrettanto probabile.

Se riesci a escludere completamente i due precedenti, sono attualmente sconcertato.

Come esperimento, puoi provare altri formati grafici, ma PNG dovrebbe andare bene. Dovrò pensarci un po 'di più per trovare una risposta migliore.


1
+1 per scartare i voti negativi ingiustificati poiché penso che tu abbia offerto alcuni suggerimenti ragionevoli e stavi solo cercando di aiutarti e, soprattutto, non c'era nulla di sbagliato nei tuoi suggerimenti.
jpierson,

1

Ho provato a utilizzare RenderOptions.BitmapScalingMode = HighQuality, sembra che causi alcuni problemi in Windows 8.1, quindi quello che ho fatto è stato eseguirli attraverso lo strumento chiamato PngOut.exe

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

Ciò riduce l'intestazione del png e riduce anche le dimensioni, ma senza cambiare la qualità dell'immagine.

E ora tutte le mie immagini sono perfette! :-)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.