12

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!

Example on low-DPI display (96dpi) Example on high-DPI display (~122dpi)

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:

  1. http://blogs.msdn.com/b/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx
  2. http://www.nbdtech.com/Blog/archive/2008/11/20/blurred-images-in-wpf.aspx
  3. http://www.hanselman.com/blog/BeAwareOfDPIWithImagePNGsInWPFImagesScaleWeirdOrAreBlurry.aspx
  4. 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); 
Community
  • 1
  • 1
freakinpenguin
  • 831
  • 14
  • 24

2 Answers2

3

Your icons are bitmaps so you are not going to solve this problem IMHO. You need to look at for a different solution. You want your icons to be device independent so you need to either convert for images to vectors or convert your images to xaml. This question have been asked and answered before and the solution does not involve much effort.

create-vector-from-image

convert-svg-to-xaml

Community
  • 1
  • 1
RussellEast
  • 153
  • 8
  • Sorry Russell, but I don't think that I must have vector icons. As you can see in the pictures in my post the images can look nice & sharp! – freakinpenguin Apr 28 '14 at 10:28
  • They do look nice when that are rendered at the resolution that were designed for. Try converting one image to a vector and see how it goes. Hopefully it works for you. – RussellEast Apr 28 '14 at 10:33
  • They look also sharp in lower resolutions than they were designed for (which is my case). I know vector graphics will work, but I don't want to convert all images to vector-graphics (>200 images). There MUST be a way to display images just like in WindowsForms. – freakinpenguin Apr 28 '14 at 10:40
  • 1
    Not the ideal solution, but have to tried to use a scale transform in xaml? – RussellEast Apr 28 '14 at 10:47
  • So I tried setting the size of the image to the size of the bitmap (96x96) and applied an scale-transform with 1/3. Unfortunately the result looks like the linear-scaling-mode in the image in my post :( But it was worth a try! – freakinpenguin Apr 28 '14 at 11:42
0

According to this post (from the esteemed creator of VirtualDub), WPF's high-quality "fant" method isn't really that great. Your custom control uses the superior bicubic method.

The subject of resampling goes pretty deep; see the links in Old Pro's answer to a question on downscaling quality, especially this one.

Community
  • 1
  • 1
Mark
  • 374
  • 4
  • 9
  • Thanks for sharing the link! Seems like this is exactly my problem. Unfortunately there's not much I can do than waiting for Microsoft to fix the behaviour. – freakinpenguin Jul 17 '15 at 13:27