1)渲染范围不正确
利用RenderTargetBitmap.Render渲染一个Canvas对象的图像,如果Canvas被一个Border包含则没有问题,但如果这个Canvas没有被Border所包含,那渲染出来的图像范围会有问题。
private void miScreenshot_Click(object sender, RoutedEventArgs e)
{
FrameworkElement visual = myChart as FrameworkElement;
RenderTargetBitmap bmp = new RenderTargetBitmap((int)visual.ActualWidth, (int)visual.ActualHeight
, 96, 96, PixelFormats.Pbgra32);
bmp.Render(visual);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
SaveFileDialog dlg = new SaveFileDialog();
dlg.Filter = "图像文件 (*.bmp)|*.bmp";
if (dlg.ShowDialog().Value)
{
using (Stream stream = File.Create(dlg.FileName))
{
encoder.Save(stream);
}
if(File.Exists(dlg.FileName))
{
Process.Start(dlg.FileName);
}
}
}
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Menu Grid.Row="0">
<MenuItem x:Name="miViews" Header="视图演示">
<!--视图DEMO-->
</MenuItem>
<MenuItem Header="设置">
<MenuItem x:Name="miOverlap" Header="视图叠加" IsCheckable="True"/>
<Separator/>
<MenuItem Header="截图" Click="miScreenshot_Click"/>
</MenuItem>
</Menu>
<Border Grid.Row="1">
<Canvas x:Name="myChart"/>
</Border>
<!--渲染范围不对
<Canvas x:Name="myChart" Grid.Row="1"/>
-->
</Grid>
有Border截图:
无Border截图:
2)渲染速度慢
相对于GDI+而言,通过WPF提供的RenderTargetBitmap.Render函数渲染一个Visual对象获得图像的方式显得过于耗时。如果做软件界面截屏功能还可以接受,但如果是连续截屏制作视频文件,则很难接受。
Stopwatch sw = new Stopwatch();
private void miScreenshot_Click(object sender, RoutedEventArgs e)
{
FrameworkElement visual = myChart as FrameworkElement;
RenderTargetBitmap bmp = new RenderTargetBitmap((int)visual.ActualWidth - 1, (int)visual.ActualHeight - 1
, 96, 96, PixelFormats.Pbgra32);
sw.Restart();
bmp.Render(visual);
sw.Stop();
Console.WriteLine("耗时 {0}ms for {1:N0}x{2:N0}像素", sw.ElapsedMilliseconds, visual.ActualWidth, visual.ActualHeight);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
SaveFileDialog dlg = new SaveFileDialog();
dlg.Filter = "图像文件 (*.bmp)|*.bmp";
if (dlg.ShowDialog().Value)
{
using (Stream stream = File.Create(dlg.FileName))
{
encoder.Save(stream);
}
if(File.Exists(dlg.FileName))
{
Process.Start(dlg.FileName);
}
}
}
输出结果:
耗时 19ms for 509x291像素
耗时 29ms for 670x401像素
耗时 24ms for 813x481像素
耗时 38ms for 964x626像素
耗时 42ms for 1,150x714像素
耗时 39ms for 1,280x941像素
额,这次的测试结果还算不错,但在某台机器上测试像素较小时也是20ms左右,但1000x700像素的耗时居然要170+ms。。。