As many people have already discovered Microsoft made a change in the.net framework resulting in the quality of bitmap scaling being reduced by default. This is because the default mode is now low quality, rather than high-quality. Optionally you can go back to the way it was previously, but this requires you to turn this feature on.
It is very disappointing that Microsoft have chosen to break backwards compatibility in this way. Apparently it was to help some customers to were experiencing slow image scaling. Why they were not just told to set the default to low quality image scaling, rather than forcing everyone in this mode is beyond me! In another similar situation they specifically didn't change the default font scaling mode, designed to increase text quality because it would break existing applications. Why they did not apply the same theory to this feature is confusing at the least.
Details of the changes are here:.
Crappy Image Resizing in WPF? Try RenderOptions.BitmapScalingMode
I have found the best way to ensure that this feature used throughout a program is to set the default scaling mode in the window constructor:
public MainWindow()
{
InitializeComponent();
RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.);
}
However, this does not deal with a situation where you need to use RenderTargetBitmap, for which this setting does not apply. You might use RenderTargetBitmap in a situation where you want to resize an image, something like this:
RenderTargetBitmap result = new RenderTargetBitmap(newWidth, newHeight, 96, 96, PixelFormats.Default);
DrawingVisual vis = new DrawingVisual();
using (DrawingContext dc = vis.RenderOpen())
dc.DrawImage(Image, new Rect(0, 0, newWidth, newHeight));
result.Render(vis);
So obviously you would probably try and do this:
RenderOptions.SetBitmapScalingMode(vis, BitmapScalingMode.HighQuality);
Which would do nothing. Unfortunately, Microsoft's support of this particular problem has been extremely poor with no responses in newsgroups or in comments on blogs. I e-mailed Pete Brown, and received no response.
As it turns out, thankfully there is a workaround. You just need to recode,using a DrawingGroup (I found the solution here: http://xiu.shoeke.com/2010/07/15/resizing-images-with-wpf-4-0/) and set the attached property on the DrawingGroup. e.g:
RenderTargetBitmap result = new RenderTargetBitmap(newWidth, newHeight, 96, 96, PixelFormats.Default);
var group = new DrawingGroup();
RenderOptions.SetBitmapScalingMode(group, BitmapScalingMode.HighQuality);
group.Children.Add(new ImageDrawing(Image, new Rect(0, 0, newWidth, newHeight)));
DrawingVisual vis = new DrawingVisual();
using (var drawingContext = vis.RenderOpen())
drawingContext.DrawDrawing(group);
result.Render(vis);
Which does result in a large amount of additional unnecessary code, but at least it is still possible for your application to work in WPF 4!
….Stefan