¡Mis imágenes son borrosas! ¿Por qué no funciona SnapsToDevicePixels de WPF?

165

Estoy usando algunas imágenes en mi aplicación 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" />

Pero, parecen difusos.

¿Por qué esa SnapsToDevicePixels="True"línea no previene este problema?

Zack Peterson
fuente
44
Sus enlaces de imágenes parecen haberse roto. Si todavía tiene las imágenes originales, vuelva a cargarlas en stack.imgur. Gracias.
Ilmari Karonen
1
Si ninguno de los consejos a continuación funciona de inmediato, también intente y cambie el tamaño de su imagen a un factor de 4 de ancho y alto. Entonces, en lugar de 179 X 44, intente 176 X 44.
Martin Lottering

Respuestas:

233

Es posible que desee considerar probar una nueva propiedad disponible ahora en WPF4 . Dejar el RenderOptions.BitmapScalingModeque La alta calidad o simplemente no declararlo.

NearestNeighbor funcionó para mí, excepto que condujo a mapas de bits irregulares al hacer zoom en la aplicación. Tampoco parecía corregir ningún problema técnico en el que los íconos se dimensionaban de manera extraña.

En su elemento raíz (es decir, la ventana principal) añadir esta propiedad: UseLayoutRounding="True".

Una propiedad que antes solo estaba disponible en Silverlight ahora ha solucionado todos los problemas de tamaño de Bitmap. :)

Domokun
fuente
44
Encontrará más información sobre esta nueva propiedad aquí: blogs.msdn.com/text/archive/2009/08/27/layout-rounding.aspx
Domokun
55
UseLayoutRendering = "True" es lo que usé, esto es perfecto para resolver mis imágenes borrosas. ¡Gracias!
Matt DeKrey
25
¡¡FINALMENTE!! UseLayoutRounding debe establecerse de forma predeterminada. Las imágenes aparecen como el texto original e incluso en algunos lugares (como ContextMenus, al menos para mí) se muestra más nítido que antes. Gracias Domokun!
conceder el
3
¿Supongo que aquellos de nosotros que todavía estamos atrapados en .NET 3.5 no tenemos opciones?
jpierson
2
Me doy cuenta de que esto soluciona mi problema si configuro la propiedad Estirar en Ninguno en las imágenes, pero en todos los demás escenarios, incluso con el renderizado y el alias de imágenes de Alta Calidad desactivados, el estiramiento de imágenes todavía es una mierda en WPF. Pero, al menos, esto ha solucionado el problema de las imágenes no estiradas (lo que no debería haber sido un problema en primer lugar)
Christian Findlay
74

En lugar de usar SnapsToDevicePixels, en lugar de eso lo usé RenderOptions.BitmapScalingModey ahora son agradables y crujientes.

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
fuente
1
Además, si su imagen tenía el tamaño exacto especificado en la etiqueta <Imagen>, entonces no tendría que escalarla y debería renderizarla con nitidez.
Beardo
1
No estoy seguro de que esto tenga el efecto deseado en un DPI diferente
Dave
1
Beardo, tanto el gráfico de origen como la <Imagen> tienen 20 píxeles por 20 píxeles. Según tengo entendido, el problema proviene de WPF. Más o menos quiere ignorar la cuadrícula de píxeles del monitor, por lo que su cuadrícula lógica generalmente no se alineará perfectamente con la cuadrícula física.
Zack Peterson el
9
@Zack Width = "20" no significa 20 píxeles. Significa 20/96 de pulgada. Si su sistema operativo está configurado para ejecutarse a 96 DPI, entonces es de 20 píxeles. Ahora, ¿cómo se verá su vecino más cercano en un buen monitor, 160 DPI, por ejemplo? ¿Y cómo se verá cuando imprima a 300 DPI? No debe optimizar para su máquina de desarrollo.
Frank Krueger
2
También descubrí que para imágenes de tamaño de píxel, NearestNeighbor es mucho mejor que HighQuality, especialmente si lo combina con img.Width = imgSource.PixelWidth; img.Height = imgSource.PixelHeight. Mi cliente proporcionó algunas imágenes con diferentes valores de DPI locos y no pude pedirle al cliente que las convirtiera todas, así que tuve que usar este truco.
JustAMartin
23

+1 para Zack Peterson

Estoy usando .Net 3.5 sp1 y parece la solución más simple para una gran cantidad de imágenes borrosas. No es un gran problema especificar RenderOptions en el lugar, pero para los componentes de terceros tiene sentido un estilo en los recursos de nivel de aplicación:

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

Funcionó bien cuando AvalonDock comenzó a representar iconos borrosos.

DK.
fuente
1
AvalonDock también me está dando los mismos dolores de cabeza ... y todavía estoy con .Net 3.5
Ignacio Soler Garcia
9

El uso UseLayoutRounding="True"de la ventana en la raíz funciona en muchos casos, pero encontré un problema al usar el control WPF Ribbon . Mi aplicación se basa en las fichas contextuales que aparecen de acuerdo a lo que el usuario está haciendo y cuando me puse la UseLayoutRoundinga True, la ficha contextual no se presentaba y la imagen del RibbonButton ninguno. Además, la aplicación se congela durante muchos segundos y el ventilador de la CPU comienza a cantar.

El uso RenderOptions.BitmapScalingMode="NearestNeighbor"en mi imagen corrigió los problemas de representación de la imagen (imagen borrosa y recortada) y es totalmente compatible con el uso de las pestañas contextuales de la cinta de opciones.

Omid B.
fuente
1
UseLayoutRounding = "True" funcionó para mí. Gracias. mikecroteau.wordpress.com/2013/01/20/wpf-net-xaml-blurry-images
mcroteau
6

RenderOptions.BitmapScalingMode = "NearestNeighbor" funciona bien la mayor parte del tiempo. Sin embargo, ocasionalmente obtendrá fallas gráficas (en mi caso, 4 de 5 imágenes aparecieron bien, pero la quinta tenía una ligera distorsión en el borde derecho). Lo arreglé aumentando mi margen derecho del control de imagen en 1.

Si eso aún no lo soluciona, pruebe el control de clase de mapa de bits anterior que EugeneZ menciona. Es un reemplazo para el control de imagen y hasta ahora me ha funcionado bastante bien. Ver http://blogs.msdn.com/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx


fuente
5

Asegúrese de guardar la imagen en el mismo DPI que su aplicación WPF está trabajando, algunos formatos de imagen tienen esta información almacenada como metadatos. No sé si esto resuelve el problema, pero he tenido algunos problemas debido a esto, donde las imágenes redimensionadas al 100% se hicieron más grandes o más pequeñas de lo esperado.

Podría ser algo similar.


fuente
5

use UseLayoutRounding = True para el elemento más alto en su aplicación

Varatharaj
fuente
3

He encontrado que RenderOptions.BitmapScalingMode = "NearestNeighbor" no funciona para mí. Estoy usando Windows XP x32 con DirectX 9.0c. Como el renderizado real para WPF se realiza con DirectX, esto podría tener un efecto. Tengo activado el suavizado para XP con las siguientes entradas de registro:

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

Sin embargo, desactivar aa con estos ajustes no tiene efecto en las imágenes. Creo que esto solo afecta a las vistas 3D.

Finalmente, descubrí que el desenfoque ocurre con el texto de TextBlocks, así como con las imágenes. Y el desenfoque solo ocurre para algunos bloques de texto e imágenes, no para todos.

luego
fuente
3

He descubierto que ninguna combinación de las soluciones sugeridas curaría mi problema de imagen borrosa aparentemente aleatorio. Me gusta que muchos otros no puedan actualizar a .net 4 para usar la UseLayoutRenderingpropiedad.

Lo que he encontrado que funciona:

  • Asegúrese de que las dimensiones de su imagen [original] sean múltiplos de 2. Esto parece evitar algunos de los problemas de escalamiento de la imagen funky.
  • A veces también descubrí que ajustar los márgenes de las imágenes en un píxel o 2 puede evitar el problema.
Jahhai
fuente
1

Mi primer pensamiento, al leer la pregunta, fue que estaba explotando demasiado la imagen, pero ese no parece ser el caso al mirar la imagen que tiene de la aplicación.

El segundo pensamiento es la paleta de colores, pero con el negro como uno de los colores que no se procesa correctamente, esto no es tan probable.

Si puede descartar por completo los dos anteriores, actualmente estoy perplejo.

Como experimento, puede probar otros formatos gráficos, pero PNG debería estar bien. Tendré que pensarlo un poco más para encontrar una mejor respuesta.

Gregory A Beamer
fuente
1
+1 para evitar votos negativos injustificados, ya que creo que ofreció algunas sugerencias razonables y solo estaba tratando de ayudar, y lo más importante, no hubo nada incorrecto con sus sugerencias.
jpierson
1

Intenté usar RenderOptions.BitmapScalingMode = HighQuality, parece que causa algunos problemas en Windows 8.1, así que lo que hice fue ejecutarlos a través de la herramienta llamada PngOut.exe

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

Lo que reduce el encabezado de png y también reduce el tamaño, pero sin cambiar la calidad de la imagen.

¡Y ahora todas mis imágenes son perfectas! :-)

MMM
fuente