代码改变世界

WPF将控件保存为图片

2011-06-22 00:04  Franz  阅读(2375)  评论(0编辑  收藏  举报

我们很多时候想把软件当前的界面内容保存为图片,在WPF中是非常简单的,RenderTargetBitmap就是专门用来干这个滴,鉴于很多朋友问我这个问题,我特此把相关的源代码在这里展示一下。

先看一下简单的XAML代码。里面只放置了一个按钮(点击按钮我们执行动作),一个图像控件(用来装我们的图片的。)

<Window x:Class="CaptureImage.Window1"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
Title
="CaptureImage" Height="300" Width="300"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button x:Name="captureBtn" Content="capture" Click="CaptureBtn_Click"/>
<Image x:Name="img" Grid.Row="2"/>
</Grid>
</Window>

接下来在看一下后台代码,

/*
* Created by SharpDevelop.
* User: Franz
* Date: 2011-6-27
* Time: 22:24
*
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace CaptureImage
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}

void CaptureBtn_Click(object sender, RoutedEventArgs e)
{
this.img.Source = this.CreateElementScreenshot(this);
//this.img.Source = this.CreateElementScreenshot(new Button(){Content = "Hello"});
}

private BitmapSource CreateElementScreenshot(Visual visual) {

RenderTargetBitmap bmp
= new RenderTargetBitmap((int)RenderSize.Width, (int)RenderSize.Height, 96, 96, PixelFormats.Default);
bmp.Render(visual);

return bmp;
}

private BitmapSource CreateNotRanderElementScreenshot(UIElement element)
{
var wantRanderSize
= new Size(300, 300);
element.Measure(wantRanderSize);

element.Arrange(
new Rect(new Point(0, 0), wantRanderSize));

return CreateElementScreenshot(element);
}


}
}

可以看到CaptureBtn_Click中有两行代码,我们先说未被注释掉的代码,很简单的调用了CreateElementScreenshot方法。可以看到当前软件界面被正确的呈现在图像控件内。

但是如果我们使用注释掉的代码来自己创建一个控件并把它显示出来。我们发现这样根本啥也不能够显示。原因其实很简单我们它并没有呈现在视觉树上,也就是说RenderTargetBitmap找不到一个合适的对象呈现来复制了。如果明天呈现那么我们就要手工的告诉它如何去呈现了。CreateNotRanderElementScreenshot方法假设了用300*300大小去呈现内容(我们可以根据自己的情况设定具体的值),通过Measure,Arrange方法告诉它要呈现多大。这样图片就被正确的显示出来了。