I'm looking for a way to prevent WPF to blur my images. I want my application to look good on high-DPI displays so I created Icons in 96x96px to display in size 32x32.
There's a lot of in google to find and even on stackoverflow there are some topics about this.
Summarized they say: Enable the property UseLayoutRounding
and set RenderOptions.BitmapScalingMode
to HighQuality
. Unfortunately this doesn't really work for me - the images still look very blurry.
Then I tested my application on a laptop with higher DPI aaaand - WOW. Images are totally sharp and nice.
My only solution was to create a custom control which converts the ImageSource to System.Drawing.Bitmap, rescales it there to match the image-dimensions and convert it back to a WPF ImageSource. Obviously not the perfect solution!
So the question is: Why look my images blurry on the low-dpi-display? I have no idea what may cause this and hope somone has an idea to fix this.
Here some of the most useful resources I found:
- http://blogs.msdn.com/b/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx
- http://www.nbdtech.com/Blog/archive/2008/11/20/blurred-images-in-wpf.aspx
- http://www.hanselman.com/blog/BeAwareOfDPIWithImagePNGsInWPFImagesScaleWeirdOrAreBlurry.aspx
- Disabling antialiasing on a WPF image
EDIT:
As requested here is the code for converting the ImageSource. There are a couple of method-calls which are not included, but you can find them really fast via google.
// Calculate the conversion factor.
float dpi = WpfImageHelper.GetCurrentDPI(this);
float factor = dpi / 96f;
int width = (int)Math.Round(this.image.ActualWidth * factor);
int height = (int)Math.Round(this.image.ActualHeight * factor);
// Create bitmaps.
Bitmap oldBitmap = WpfImageHelper.ToWinFormsBitmap2((BitmapSource)this.Source);
Bitmap newBitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// Draw the new bitmap. Use high-quality interpolation mode.
using (Graphics g = Graphics.FromImage(newBitmap))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.Clear(System.Drawing.Color.Transparent);
g.DrawImage(oldBitmap, 0, 0, newBitmap.Width, newBitmap.Height);
}
// Set the image source to the resized bitmap.
this.Source = WpfImageHelper.ToWpfBitmap2(newBitmap);