Why can't I get SnapsToDevicePixels to work
<Window x:Class="WindowsApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowsApplication1" Height="300" Width="300" SnapsToDevicePixels="True">
<Grid SnapsToDevicePixels="True">
<ScrollViewer Background="Black" HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto" SnapsToDevicePixels="True">
<Image Source="checkerboard.bmp" HorizontalAlignment="Center"
VerticalAlignment="Center" SnapsToDevicePixels="True"/>
</ScrollViewer>
</Grid>
</Window>
Here's a sample project if you want to see what I mean:
http://www.upload2.net/page/download/xzMiYdJqCsk3Efe/SimpleExample.zip.html

Help me snap to device pixels...
Michael W.
I don't think there is a good way to do this. WPF does snap the image geometry to the device pixels, producing a rectangle which is snapped. However, the location of the image itself does not get snapped. This is a little confusing, so I'll say it another way. This snapped rectangle is drawn internally with an unsnapped image brush, producing a blurry image.
One of the ways you can make more use of pixel snapping is to use geometry to describe your content instead of bitmaps. In your example, that might mean replacing your checkerboard bitmap with a DrawingImage that describes the checkerboard.
This issue does come up now and again. I'm sorry not to have a better workaround. We will be looking at improving this in the future.
-Miles
xx-Cougar-xx
In WPF, images have both an ImageWidth/Height and a PixelWidth/Height. [I'll drop the word "Height" from the future of this post.] PixelWidth is what people are used to, coming from platforms other than WPF. It is measured in pixels. ImageWidth on the other hand is measured in inches (technically 1/96th of an inch). So when you ask that an image be placed in a certain location without stretching, the thing that WPF doesn't stretch is the number of inches that the image takes up. The pixels in the underlying bitmap can still be stretched to make this work.
For a screen capture tool, I think you'd want to ensure that the BitmapImage DPI is the same as the DPI of the monitor. I've never done this from managed code, but I trust that it is possible. If your BitmapImage DPI is the same as the display, then this should mean that your image is not stretched.
Now... if you know the DPI of the display you are targeting* as it looks like you will, you can work around some of the Image centering issues. The reason the images look blurry is not because they are centered, but because they are not positioned exactly on a pixel boundary. So, if you can change the size of the element that the image is centered within, this can allow the image to be centered and not-blurry. If you have an even number of pixels in the bitmap, you should make sure the element it is cenered within also has an even number of pixels. And if there are an odd number of pixels in the bitmap, the element it is within must be odd. If you can dynamically change the size of your elements based on DPI, you might be able to achieve this... though this will mean responding to mode changes if you really want to get it right.
But image centering is not the only thing that can cause an image to be unaligned. If you position an image at the top left of another element, but that element is positioned, say 5/96ths of an inch from the left side of the window, this will mean that your image will be aligned to device pixels on a 96 DPI monitor, but on a 120 DPI monitor it will not be aligned. Turning on pixel snapping here again won't help. You'd need to change the location of the element based on DPI and this is something WPF does not do. Pixel snapping instead just moves the geometry that the element internally draws itself with.
* A thing to watch for: Part of the problem with knowing the DPI and making decisions based on it is that a system can have multiple displays, each with a different DPI. This is a nasty situation to account for, and WPF doesn't handle it perfectly itself today. Nevertheless, know that it can happen, and be aware that you may need to add extra fudge if you want to try and support this scenario.
Johnson Road
Rebecca23
danielo1
NorbertHH
Ajeeth Kumar
To completely answer the questions posed in this thread, Miles and Anthony put together a great post explaining the details of how to best place an image in WPF:
http://blogs.msdn.com/seema/archive/2006/11/07/why-do-my-bitmaps-look-blurry-by-anthony-hodsdon-miles-cohen.aspx
Best, SeemaR
Jayson Speer
Wow, I've got to admit I'm surprised there's no approach for this. I created the checkerboard bitmap simply because it illustrates the point. In reality, my app is doing screen captures (like the Vista snipping tool). If the pixels don't align with hardware pixels, then it really looks bad. I guess for now, I'll just have to align it with the top left corner. Unfortunately, that screws up the visual balace of the containing Window.
Perhaps you could help me address another related issue... When I change my dpi setting to anything other than 96, I get stretching problems. I understand why that's happening, and it makes sense. However, I can't figure out how to programmatically get Window's dpi setting in order to apply the appropriate transformation.
I realize the rationale for device independent pixels and I absolutely love the way the vector compositing works. However, putting bitmaps in applications, either as the content of an image viewer control or as part of the UI, isn't going away anytime soon. The Vista shell, including apps like WMP 11, are still bitmap based. It's surprising that it's somewhat difficult to work with bitmaps in WPF. I guess I was anticipating better interoperability between vector and raster functionality in the framework. Just giving an Image control a ForceBitmapPixelsToHardwarePixels property would be a huge help.
Sandhya