如何使图像不拉伸?

7

[imgur已删除图片]

左侧的图标是以下代码的结果:

    <Button Height="23" HorizontalAlignment="Left" Margin="12,276,0,0" Name="button1" VerticalAlignment="Top" Width="75">
        <StackPanel Orientation="Horizontal">
            <Image Source="Resources/add.png" Stretch="None" />
            <TextBlock Margin="5,0,0,0" Text="Add" />
        </StackPanel>
    </Button>

右边的那张图片是使用Photoshop放置的原始图像。似乎通过代码添加的那张图片被拉伸了一个像素,导致一些失真。我该如何避免这种情况?


如果在XAML中明确设置宽度和高度属性会发生什么? - Eugen
@Eugen:我也试过了,但没有改变任何东西。如果我将其设置小一个像素,则大小就正确了,但由于缩放仍然会模糊。 - mpen
图片已损坏... - itsho
@itsho:Imgur可能已经删除了它。很抱歉我没有另一份副本给你。不过它与这个很相似:http://i.imgur.com/xV08C.png - mpen
8个回答

9

Stretch="None" 的作用就是不对图片进行拉伸。如果显示效果有差异,可能是由于像素处于“边缘”的原因。

您可以尝试设置 SnapsToDevicePixels=“True” 以避免这种情况。


不行...这也不行。 - mpen
设置附加属性怎么样:RenderOptions.BitmapScalingMode="HighQuality"(或者其他值呢)? - H.B.
@HB: 不应该进行缩放,但是无论如何,我试过了,还是看起来一样。 - mpen
1
正如Velja Matic所指出的那样,我认为在这种情况下,“NearestNeighbor”实际上是一个不错的选择。它仍然可以缩放,而且这个属性不受“Stretch”的影响。 - H.B.

4

添加Stretch=None可以防止图像重新调整大小

<ImageBrush ImageSource="rtgEnhanced.png" AlignmentX="Left" AlignmentY="Bottom" Stretch="None"></ImageBrush>

4

使用第一个链接建议的 UseLayoutRounding 起作用了。第二个链接提供了很好的解释。谢谢! - mpen

3

我无法真正看到你的示例中发生了什么,但是WPF出现这种问题的一个非常常见的原因是PNG文件中的DPI值不是96(通常是72,如果它来自具有Mac遗产的任何东西)。


那么,我如何检查DPI值以及如何修复它?这是来自famfamfam的silk图标集中未编辑的图标。 - mpen
1
@Mark,在Photoshop中,使用“图像/调整大小…”,首先取消“重新取样”选项。然后输入新的像素/英寸值并按“确定”。您图像的像素尺寸不会改变,但当您重新保存PNG时,新的元数据将被编写。确实,dpi值不等于96意味着WPF在Image.Stretch="None"时不会使用本地像素大小。非常感谢Will提供这个神奇的修复。 - Glenn Slayden
如果有人需要DPI校正工具:您可以使用免费且易于使用的Paint.NET来完成此任务。 - Beauty

3
PNG图像中可以存储一个称为pHYs块的东西。该块定义了图像预期显示的DPI。如果图像的DPI与监视器的DPI不匹配,则WPF会将其拉伸以使其以“预期”大小显示。这通常(至少对我来说)与我的意图完全不符,会引起很多沮丧。
为了消除“预期”的拉伸,一种选择是从PNG中删除pHYs块。
您可以使用TweakPNG之类的工具检查和删除pHYs。
另外,您也可以使用正确的DPI编码保存图像,或者根本不保存,假设您的图像编辑软件支持此功能。

PngOptimizer对我很有帮助:http://psydk.org/pngoptimizer - Lenor

1
我只能通过显式设置宽度或高度来解决这个问题。因此,如果您知道图像的高度为48像素,请按照以下方式操作:
<Image Source="myImage.png" Height="48" UseLayoutRounding="True"/>

1

实际上,NearestNeighbor将允许引擎在缩放时跳过源图像中的像素。如果有线性选项,那可能会更好,因为它意味着从源图像逐像素读取进行缩放。


你说得完全正确,如果你读一下我在被采纳的答案下面留的评论,你会发现这也是我发现的。我标记它为正确是因为他的建议 UseLayoutRounding 解决了这个问题。 - mpen

0

这个方法对我起了作用:

在你的根元素上(例如你的主窗口)添加以下属性:UseLayoutRounding="True"

来源


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