WPF中的图像变得模糊

Posted

技术标签:

【中文标题】WPF中的图像变得模糊【英文标题】:Image in WPF getting Blurry 【发布时间】:2011-08-04 10:55:05 【问题描述】:

我正在使用 C# 在 WPF 中开发应用程序。我将图像放在 WrapPanel 中,并在带有一个边框的网格内显示,并在按钮中使用图像。问题是我的图像控制失去了质量。我无法在这里发布我的图片,所以我只是在这里进行描述。

我使用SnapsToDevicePixels="True" 制作图像,但看起来还是很模糊。

更新:

在这里我分享了下面的图片:

【问题讨论】:

你是想让图片比原来的尺寸大还是小? 不,我用它的原始尺寸修复了 My images are blurry! Why isn't WPF's SnapsToDevicePixels working?的可能重复 【参考方案1】:

我认为 Markus 所说的是解决您的问题的一种方法,并尝试在其中添加一个属性 RenderOptions.EdgeMode="Aliased" 我的意思是每张图片:

<Image Source="/LoginPanel;component/Icons/icoLogin.ico"
       RenderOptions.BitmapScalingMode="NearestNeighbor"
       RenderOptions.EdgeMode="Aliased"/>

如果您仍然无法解决问题,那么您可以参考此http://blogs.msdn.com/b/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx 来创建自定义位图类并应用于所有给您带来麻烦的图像。

你也可以看到这个Stack Overflow Question

【讨论】:

感谢您的精彩回答 :) @Turtleneck:我认为这是***.com/questions/592017/…的重复问题 最近的邻居为我解决了这个问题。谢谢!【参考方案2】:

SnapsToDevicePixels 似乎不适用于位图。

NearestNeighbor 选项实际上会转换位图,最终会得到与原始位图不同的位图。

在 WPF 4 中,在 FrameworkElement 上引入了一个属性“UseLayoutRounding”来解决这个问题。

通过在根元素上将此属性设置为 True,例如 Window 将在像素边缘对齐子元素。

<Window UseLayoutRounding="True">...</Window>

【讨论】:

这甚至比使用 NearestNeighbor 缩放模式更好,因为它保留了图像的原始像素。谢谢 这对我有用,但我发现它不需要需要在根元素上。一个父元素,甚至是目标元素也会达到想要的效果。【参考方案3】:

这对我有用

<Image Source="/LoginPanel;component/Icons/icoLogin.ico"
       RenderOptions.BitmapScalingMode="NearestNeighbor"</Image>

为每个图像设置 RenderOptions.BitmapScalingMode="NearestNeighbor"。或者在 *** 上查看此 question。

编辑: 这是我的示例代码

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="661">
    <WrapPanel>
        <Button VerticalAlignment="Center">
            <Image Source="/WpfApplication1;component/icoChip32x32.ico"
               RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="None"></Image>
        </Button>
        <Button VerticalAlignment="Center">
            <Image Source="/WpfApplication1;component/icoChip32x32.ico"
                   RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="None"></Image>
        </Button>

        <Button VerticalAlignment="Center">
            <Image Source="/WpfApplication1;component/Presentation-Edit.png"
               RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="None"></Image>
        </Button>
        <Button VerticalAlignment="Center">
            <Image Source="/WpfApplication1;component/Presentation-Edit.png"
                   RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="None"></Image>
        </Button>
    </WrapPanel>
</Window>

这是我的结果:

【讨论】:

它非常适合图像,但会在图像周围折腾,我的意思是边框变得褪色,周围有不止一个条带。如果您不介意,请分享您拥有的任何示例应用程序 我的示例代码看不到任何问题。也许您可以尝试小幅度的实验?你能发布更多你的代码吗? 感谢您的出色回答我通过为我的位图使用自定义类解决了这个问题 :)【参考方案4】:

如果图像用作内容,则在父元素上使用 UseLayoutRounding="True" 属性。在您的情况下,它是按钮。

【讨论】:

【参考方案5】:

我遇到了由缩放引起的图像背景模糊问题,解决方案比您想象的要简单得多。起初我想知道它是否被放大到两倍的纹理大小,但缩放实际上与系统 DPI (96) : 图像 DPI (72,这是许多编辑器的默认值) 的比率相匹配。如果您将图像调整为 96 DPI,则它应该在默认的 Windows 设置下显示像素完美。

编辑:尝试了具有高细节对比度的图像,并且略微柔和了。

【讨论】:

【参考方案6】:

WPF 不使用具体的像素值来确定大小和位置,因此它可以很好地使用 DPI 进行缩放。

这可能会导致它尝试使用与屏幕上离散像素不对应的位置;一些图像像素被渲染在我们认为模糊的多个屏幕像素上。

UseLayoutRendering=true 和 SnapToDevicePixels=false 应该可以解决这个问题。您还需要在主窗口级别设置它,以便计算级联到图像级别。

您可以通过创建一个带有一个窗口和图像的简单 WPF 应用程序来尝试这一点。将图像边距设置为 (10.452, 0.736, 0, 0) 之类的东西会导致模糊。这会在图像上使用 UseLayoutRendering=true 时消失。

如果您在 InitializeComponent() 之后在窗口的构造函数中再次设置边距,则无论您是否在图像上设置 UseLayoutRendering=true,它都会变得模糊,因为与屏幕像素对齐的计算是在您之前进行的将图像移动到与这些不匹配的位置。

我不完全确定 UseLayoutRendering 和 SnapToDevicePixels 之间有什么区别 - 我认为这只是进行计算的时间。 UseLayoutRendering 似乎更适合图像。

从原始尺寸拉伸/压缩图像也会导致模糊问题。

【讨论】:

非常感谢!您的解决方案是唯一对我有用的解决方案! 想发表评论说这也对我有用。 SnapsToDevicePixels="False" 和 UseLayoutRounding="True" 给出了最好的结果。【参考方案7】:

我遇到了同样的问题,但在我的情况下,我下载了图标并发现它们的 DPI 也都错误...... 110,56 和 116,xx 和 95,99 等等......

当我将所有的 DPI 更改为 96 时,一切都很好!

【讨论】:

以上是关于WPF中的图像变得模糊的主要内容,如果未能解决你的问题,请参考以下文章

Direct2D,WPF D3D10 图像在调整大小时模糊

文本渲染仍然模糊:WPF 应用程序的最佳字体?

我的图像很模糊!为啥 WPF 的 SnapsToDevicePixels 不起作用?

Xamarin Forms Map 中的地图模糊?

如何缩小 UIImage 并使其同时变得清晰/锐利而不是模糊?

为啥在 webkit 浏览器下缩放 SVG 会变得模糊?