RenderTargetBitmap缺陷

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。。。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值