I am using a DrawingContext to draw images. I then render the result to a RenderTargetBitmap. The image is crisp & sharp on the screen, but becomes blurred when saved. Even on 100% scaling the issue persists. Interesting part is that if the image width is less than 2000px it exports fine. But as the width increases, exported image keeps getting more and more blur.
Here is my code ( Sample project )
private void Window_Loaded(object sender, RoutedEventArgs e)
{
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri(@"image-full-hd.png");
bitmap.EndInit();
img1.Source = bitmap;
img1.Width = bitmap.Width;
img1.Height= bitmap.Height;
}
private void btnExport_Click(object sender, RoutedEventArgs e)
{
var result = CaptureSnapshot(img1);
Clipboard.SetImage(result);
}
public BitmapSource CaptureSnapshot(UIElement source)
{
var dpi = VisualTreeHelper.GetDpi(source);
double dpiX = dpi.DpiScaleX, dpiY = dpi.DpiScaleY;
double newImageWidth = source.RenderSize.Width * dpiX;
double newImageHeight = source.RenderSize.Height * dpiY;
RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)newImageWidth, (int)newImageHeight, 96, 96, PixelFormats.Pbgra32);
DrawingVisual visual = new DrawingVisual();
using (DrawingContext context = visual.RenderOpen())
{
VisualBrush sourceBrush1 = new VisualBrush(source)
{
Stretch = Stretch.None
};
context.DrawRectangle(sourceBrush1, null, new Rect(source.RenderSize));
}
System.Windows.Size s1size = new System.Windows.Size(newImageWidth, newImageHeight);
source.Measure(s1size);
source.Arrange(new Rect(s1size));
RenderOptions.SetEdgeMode(renderTarget, EdgeMode.Unspecified);
RenderOptions.SetBitmapScalingMode(renderTarget, BitmapScalingMode.HighQuality);
renderTarget.Render(visual);
return renderTarget;
}
If the source UIElement has already been rendered - and you are using its
RenderSize
for calculating the size of the bitmap - there is no need for another layout pass, so the Measure and Arrange calls seem unnecessary.In order to create an unblurred DrawingVisual output of the scaled original image, you could directly draw the
ImageSource
of the Image element into the Visual when thesource
argument is an Image. Use a VisualBrush only whensource
is not an Image.