我正在使用DrawingContext来绘制图像。然后将结果渲染为RenderTargetBitmap。图像在屏幕上清晰锐利,但保存时变得模糊。即使在100%扩展的情况下,问题仍然存在。有趣的是,如果图像宽度小于2000px,则可以导出。但随着宽度的增加,导出的图像变得越来越模糊。
下面是我的代码(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;
}
应用窗口
从3400px宽的导出图像剪辑
2条答案
按热度按时间tsm1rwdh1#
如果源UIElement已经被渲染--并且您正在使用它的
RenderSize
来计算位图的大小--则不需要另一个布局过程,因此Measure和Arrange调用似乎是不必要的。为了创建缩放原始图像的未模糊DrawingVisual输出,当
source
参数是Image时,可以直接将Image元素的ImageSource
绘制到Visual中。仅当source
不是图像时才使用VisualBrush。rkttyhzu2#
是否需要使用
DrawingVisual
、DrawingContext
和VisualBrush
?因为如果没有,您可以直接将UIElement
传递给RenderTargetBitmap.Render()
。我克隆了你的示例项目,并将CaptureSnapshot
改为:并且项目中的两个示例图像的结果都不会显示模糊。
编辑
由于需要使用
Visual
,我又做了一些搜索,发现了this thread。你可以使用BitmapCacheBrush
,将SnapsToDevicePixels
设置为true
,它应该可以在没有模糊的情况下工作: