Silverlight 3 开始支持 WriteableBitmap。WriteableBitmap 是一个可写入并可更新的 BitmapSource。BitmapSource 是 WPF/Silverlight 图像处理管线的基本构造块,从概念上说表示具有特定大小和分辨率的单个不变的像素集。
他们类的继承层次结构如下:
System.Object
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Freezable
System.Windows.Media.Animation.Animatable
System.Windows.Media.ImageSource
System.Windows.Media.Imaging.BitmapSource
System.Windows.Media.Imaging.BitmapFrame
System.Windows.Media.Imaging.BitmapImage
System.Windows.Media.Imaging.CachedBitmap
System.Windows.Media.Imaging.ColorConvertedBitmap
System.Windows.Media.Imaging.CroppedBitmap
System.Windows.Media.Imaging.FormatConvertedBitmap
System.Windows.Media.Imaging.RenderTargetBitmap
System.Windows.Media.Imaging.TransformedBitmap
System.Windows.Media.Imaging.WriteableBitmap
System.Windows.Interop.InteropBitmap
需要注意的,上面的结构是WPF中支持的,Silverlight 3仅支持上面红色的那两个,其他的不支持。
MSDN 网站描述这个类的用途如下:
使用 WriteableBitmap 类一帧一帧地更新和呈现位图。这对于拍摄视频播放快照、生成算法内容(如分形图像)和数据可视化(如音乐可视化应用程序)很有用。
WriteableBitmap主要有两种使用方法:
使用类的构造函数呈现位图
下面我就来演示一个最简单的使用 WriteableBitmap 类的构造函数演示位图的例子,这个例子截文本输入框中的图到右边列表框中。
Xaml 文件:
UserControl x:Class="Silverlight_WriteableBitmap.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
StackPanel Orientation="Horizontal"> StackPanel Orientation="Vertical" > TextBox x:Name="tb_Txt" Width="200" Height="150" AcceptsReturn="True" TextWrapping="Wrap" Text="测试测试"/> Button x:Name="btn_printScreen" Width="100" Height="39" Content="截屏" Margin="50" Click="btn_printScreen_Click" /> StackPanel> ListBox x:Name="listBox" Width="200" /> StackPanel> UserControl>
C#代码文件:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Windows.Media.Imaging; namespace Silverlight_WriteableBitmap { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void btn_printScreen_Click(object sender, RoutedEventArgs e) { WriteableBitmap bitmap = new WriteableBitmap(tb_Txt, null); Image img = new Image(); img.Height = 150; img.Width = 150; img.Source = bitmap; img.Stretch = Stretch.Uniform; ListBoxItem item = new ListBoxItem(); item.Content = img; listBox.Items.Add(item); } } }
说明:
上面例子中,我们使用的是 public WriteableBitmap(UIElement element, Transform transform) 这个构造函数。element 是要在位图中呈现的元素;transform 是用户在绘制到位图之前最后一步应用到元素的变换。如果您希望位图将元素的变换考虑在内,则这对于您特别有意义。此值可为 null。
这个 WriteableBitmap 构造函数适用于绝大多数的"复制内容"方案。这个构造函数可生成在保留内容基础下,尽量减少空白的 PBGRA32格式(采用32BPP的一种基于sRGB的像素格式)的 WriteableBitmap。它把 element 的各种变化都考虑进去了,这些变化包括:Clip,Effect,Opacity,OpacityMask,Children。当然还有一些变化没有包含,这时候,我们可以对他的父控件进行截屏,就可以扑捉到这些没有包括的变化。另外:WriteableBitmap 不能呈现弹出式控件,如 Popup、ComboBox 和 ToolTip。
使用Render多次呈现位图
另外, 如果您希望多次呈现此位图,则使用 Render 方法。如果您使用 Render 方法,则需要调用 Invalidate 以便呈现位图。 当向位图中的像素分配颜色时,请使用自左乘的颜色。
多次呈现的一个典型场景就是游戏的换肤,比如这篇博客就探讨到这个问题:Silverlight游戏中的WriteableBitmap技术可行性报告
下面的例子则是演示通过多次Render呈现,实现字体的立体效果。
演示XAML代码
UserControl x:Class="Silverlight_WriteableBitmap.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" Loaded="UserControl_Loaded">
Grid x:Name="LayoutRoot" Background="DarkGray"> Grid.RowDefinitions> RowDefinition Height="*"/> RowDefinition Height="*"/> RowDefinition Height="*"/> Grid.RowDefinitions> Border BorderBrush="Red" BorderThickness="2" Grid.Row="0"> Image x:Name="OutputImage1"/> Border> Border BorderBrush="Blue" BorderThickness="2" Grid.Row="1"> Image x:Name="OutputImage2"/> Border> Border BorderBrush="Green" BorderThickness="2" Grid.Row="2"> Image x:Name="OutputImage3"/> Border> Grid> UserControl>
C#代码部分
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Windows.Media.Imaging; namespace Silverlight_WriteableBitmap { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private WriteableBitmap SetupRenderedTextBitmap(string text, double fontSize) { // setup the textblock we will render to a bitmap TextBlock txt1 = new TextBlock(); txt1.Text = text; txt1.FontSize = fontSize; // set the font size before using the Actual Width / Height // create our first bitmap we will render to WriteableBitmap bitmap = new WriteableBitmap((int)txt1.ActualWidth, (int)txt1.ActualHeight); txt1.Foreground = new SolidColorBrush(Colors.Black); bitmap.Render(txt1, new TranslateTransform() { X = -2, Y = -2 }); txt1.Foreground = new SolidColorBrush(Colors.White); bitmap.Render(txt1, new TranslateTransform()); // invalidate the bitmap so that it is rendered bitmap.Invalidate(); return bitmap; } private void UserControl_Loaded(object sender, RoutedEventArgs e) { WriteableBitmap bitmap1 = SetupRenderedTextBitmap("http://blog.joycode.com/ghj/", 64.0D); WriteableBitmap bitmap2 = SetupRenderedTextBitmap("http://blog.joycode.com/ghj/", 24.0D); WriteableBitmap bitmap3 = SetupRenderedTextBitmap("http://blog.joycode.com/ghj/", 12.0D); OutputImage1.Source = bitmap1; OutputImage2.Source = bitmap2; OutputImage3.Source = bitmap3; } } }
演示效果如下图:
说明:
参考资料:
silverlight3新增功能2:WriteableBitmap
http://www.cnblogs.com/dino623/archive/2009/09/04/silverlight.html
用于 Silverlight 的 .NET Framework 类库 : WriteableBitmap 类
http://msdn.microsoft.com/zh-cn/library/system.windows.media.imaging.writeablebitmap(VS.95).aspx
用于 Silverlight 的 .NET Framework 类库WriteableBitmap 构造函数 (UIElement, Transform)
http://msdn.microsoft.com/zh-cn/library/dd638675(VS.95).aspx
Silverlight游戏中的WriteableBitmap技术可行性报告
http://www.cnblogs.com/Jax/archive/2010/02/02/1662287.html
Rendering Text to a WriteableBitmap with Silverlight 3's Bitmap API
http://www.smartypantscoding.com/content/rendering-text-writeablebitmap-silverlight-3s-bitmap-api