Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Blurry Images

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); 
like image 218
freakinpenguin Avatar asked Apr 28 '14 07:04

freakinpenguin


1 Answers

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

like image 199
RussellEast Avatar answered Nov 16 '22 11:11

RussellEast