我的图片很模糊!为什么WPF的SnapsToDevicePixels不起作用?

169

我在我的 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"的设置没有解决这个问题呢?


1
http://blogs.msdn.com/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx - ezolotko
4
您的图片链接似乎已经失效。如果您还有原始图片,请重新上传到 stack.imgur。谢谢。 - Ilmari Karonen
1
如果以下任何提示立即无效,也可以尝试将图像的大小更改为宽度和高度的4倍因子。因此,不要使用179 X 44,而要尝试176 X 44。 - Martin Lottering
12个回答

256

你可以考虑尝试在 WPF4 中使用的一个新属性。将RenderOptions.BitmapScalingMode保留为HighQuality或者不声明它。

NearestNeighbor 对我很有效,但当应用程序放大时会导致位图出现锯齿,而且似乎无法修复图标大小出现异常的问题。

在你的根元素(即你的主窗口)上添加这个属性:UseLayoutRounding="True"

之前只在 Silverlight 中可用的一个属性,现在已经解决了所有位图大小问题。 :)


4
此新属性的更多信息请点击以下链接:http://blogs.msdn.com/text/archive/2009/08/27/layout-rounding.aspx - Domokun
7
"UseLayoutRendering="True" 是我使用的内容 - 这对于解决我的图片模糊问题非常完美。谢谢!" - Matt DeKrey
28
终于!UseLayoutRounding 应该默认设置了。图片显示的效果与原始图像一样,甚至某些地方的文本(例如上下文菜单,对我来说)显示更加清晰。感谢 Domokun! - grant
3
我猜那些仍然停留在.NET 3.5的人没有选择吗? - jpierson
2
我发现,如果我在图像上将Stretch属性设置为None,这可以解决我的问题,但在所有其他情况下,即使关闭了高质量图像渲染和抗锯齿,WPF中的图像拉伸仍然很糟糕。但是,至少这已经解决了非拉伸图像的问题(本来就不应该成为问题)。 - Christian Findlay
显示剩余3条评论

79

我使用 RenderOptions.BitmapScalingMode 替代了 SnapsToDevicePixels,现在我的内容看起来更加清晰!

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>标记中指定的完全相同,那么它就不必进行缩放,并且应该能够清晰地呈现。 - Beardo
1
我不确定在不同DPI下这将产生预期的效果。 - Dave
1
Beardo,源图形和<Image>都是20像素乘20像素。据我所知,问题来自WPF。它有点想忽略显示器的像素网格,因此它的逻辑网格通常不会完全与物理网格对齐。 - Zack Peterson
10
@Zack Width="20" 并不代表20像素,它的意思是20/96英寸。如果您的操作系统配置为以96 DPI运行,则它将是20像素。现在,如果您的显示器是160 DPI,最近邻居会是什么样子呢?而当您以300 DPI打印时,它又会是什么样子呢?您不应该针对开发机进行优化。 - Frank Krueger
2
我还发现,对于像素大小的图像,最近邻插值比高质量插值要好得多,特别是如果你将其与img.Width = imgSource.PixelWidth; img.Height = imgSource.PixelHeight相结合。我的客户提供了一些具有不同DPI值的疯狂图片,我不能要求客户将它们全部转换,所以我不得不使用这个技巧。 - JustAMartin
显示剩余5条评论

23

+1 给 Zack Peterson

我正在使用 .Net 3.5 sp1,对于大量模糊图像来说,似乎最简单的解决方案是使用 RenderOptions。在现场指定 RenderOptions 不是什么大问题,但对于第三方组件来说,在应用程序级别的资源中定义样式是有意义的:

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

当AvalonDock开始渲染模糊的图标时,它能很好地工作。


1
AvalonDock也让我头疼不已...而且我仍在使用.Net 3.5。 - Ignacio Soler Garcia

10

在根窗口上使用 UseLayoutRounding="True" 在许多情况下都有效,但当我使用 WPF Ribbon 控件时遇到了问题。我的应用程序依赖于根据用户的操作出现的上下文选项卡,当我将 UseLayoutRounding 设置为 True 时,上下文选项卡不会显示,RibbonButton 的图像也不会显示。此外,应用程序会冻结几秒钟,并且 CPU 风扇开始旋转。

在我的图像上使用 RenderOptions.BitmapScalingMode="NearestNeighbor" 可以解决图像呈现问题(模糊和裁剪图像),并且完全兼容 Ribbon 上下文选项卡的使用。


1
UseLayoutRounding="True" 对我很有用。谢谢。http://mikecroteau.wordpress.com/2013/01/20/wpf-net-xaml-blurry-images/ - Mike Croteau

6

在你的应用程序中,将UseLayoutRounding=True应用于最顶层的元素。


6

RenderOptions.BitmapScalingMode="NearestNeighbor"通常效果良好。然而,偶尔会出现图形故障(在我的情况下,5张图片中有4张正常显示,但第五张右边缘略微失真)。我通过将Image控件的右边距增加1来解决问题。

如果仍然无法解决,请尝试EugeneZ提到的Bitmap类控件。它是Image控件的替代品,目前对我来说效果还不错。请参见http://blogs.msdn.com/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx


5

请确保将图像保存在与您的WPF应用程序工作时相同的DPI中,某些图像格式将此信息存储为元数据。我不知道这是否解决了问题,但我曾经因此遇到过一些问题,其中调整大小为100%的图像比预期更大或更小。

可能类似的情况。


3
我发现RenderOptions.BitmapScalingMode="NearestNeighbor"对我不起作用。 我使用的是带有DirectX 9.0c的Windows XP x32。 由于WPF的实际渲染是使用DirectX完成的,因此可能会产生影响。 我已经在XP上打开了抗锯齿功能,并使用以下注册表项:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Avalon.Graphics] "MaxMultisampleType"=dword:00000004 "EnableDebugControl"=dword:00000001
但是,使用这些设置关闭aa对图像没有影响。 我认为这只影响3D视口。
最后,我发现TextBlocks的文本以及图像都会模糊。 而且,模糊只会发生在某些文本块和图像上,而不是全部。

3

我发现尝试了多种方法都无法解决看似随机的模糊图像问题。和许多人一样,我无法升级到.net 4以使用UseLayoutRendering属性。

我发现以下方法有效:

  • 确保 [原始] 图像尺寸是2的倍数。这似乎可以防止一些奇怪的图像缩放问题。
  • 有时候调整图像的边距一两个像素也可以避免出现问题。

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接