5

I've encountered a problem with bitmap images in WPF. When the image container starts on a position which is not a whole number, the image seems to not respect the value of SnapsToDevicePixels.

Example code:

<Window x:Class="BlurryImage.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="110" Width="200">
    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
        <Button SnapsToDevicePixels="True">
            <Image SnapsToDevicePixels="True" Source="i16.png" Stretch="None"/>
        </Button>
        <Button SnapsToDevicePixels="True" Margin="10.333333,0,0,0">
            <Image SnapsToDevicePixels="True" Source="i16.png" Stretch="None"/>
        </Button>
    </StackPanel>
</Window>

(Note the value of the left margin: 10.333333.)

Here the image i16.png is a simple 16x16 bitmap in 96 DPI resolution with thin vertical lines: image here. (My system resolution is 96 DPI, Windows XP, .NET 4)

When I run the program, the first image is sharp, whereas the second one is blurry: blurry image screenshot

Different sources, including some here on stackoverflow, suggest different workarounds. (For example, these posts: [1], [2] and [3].) I tried the workarounds, and them seem to work. Using UseLayoutRounding="true" on the main window makes both images sharp. Using RenderOptions.BitmapScalingMode="NearestNeighbor" on the image makes it sharp, too.

The question is, why doesn't SnapsToDevicePixels="True" work without workarounds? Is it a bug in WPF or I am using it in a wrong way?

Community
  • 1
  • 1
Vlad
  • 35,022
  • 6
  • 77
  • 199

1 Answers1

5

From this blog entry:

SnapsToDevicePixels

WPF anticipated that there would be cases where people wanted to align with the pixel grid instead of using sub-pixel precision. You can set the SnapsToDevicePixels property on any UIElement. This will cause us to try and render to the pixel grid, but there are quite a few cases that don't work - including images. We will be looking to improve this in the future.

So it's just a known limitation of what SnapsToDevicePixels can do.

CodeNaked
  • 40,753
  • 6
  • 122
  • 148
  • Given that blurred images are one of the essential use cases of `SnapsToDevicePixels`, I find it pity that this bug is not mentioned in [MSDN](http://msdn.microsoft.com/en-us/library/system.windows.uielement.snapstodevicepixels.aspx). – Vlad Aug 03 '11 at 11:57
  • @Vlad - Yeah, not sure why it wouldn't work for images. Other than maybe it may need to render outside it's bounds if it tried to align to device pixels. It does seem that UseLayoutRounding should have been included from the start. – CodeNaked Aug 03 '11 at 12:03