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构造函数呈现位图
- 使用WriteableBitmap类的Render 方法呈现位图,可以多次调用Render 方法,继而实现图片的合并,游戏的换肤就可以用这种方式。
使用类的构造函数呈现位图
下面我就来演示一个最简单的使用 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;
}
}
}
演示效果如下图:

说明:
- Render 方法支持不属于可视化树的 UIElement 对象。您需要先为不在可视化树中的 UIElement 对象调用 Measure 和 Arrange,然后再调用 Render。
- 调用Render 方法之后,必须调用 Invalidate 以便呈现此位图。
- 如果元素比位图大,或者如果元素在自己空间的负区域中具有一些点,则会根据情况对它进行剪裁。
参考资料:
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
分享到:
相关推荐
在Windows Presentation Foundation (WPF) 中,WriteableBitmap 是一个非常重要的类,它允许开发者将位图作为可写的像素数组来处理。这个类是用于直接操作图像像素,从而实现高效地处理图片和视频流。在本示例中,...
但如果有时候不想依赖D3D时,还有一种方案实现视频的渲染,使用wpf的WriteableBitmap,WriteableBitmap的祖先接口有ImageSource,即可以作为Image的Source显示画面。我们只需往WriteableBitmap中写入图像数据即可...
本项目通过使用WriteableBitmap和多线程技术,结合双缓存策略,实现了高效的绘图性能。下面将详细介绍这些关键知识点。 1. **WriteableBitmap**: WriteableBitmap是WPF中用于直接像素操作的类,它允许开发者以编程...
在Windows Presentation Foundation (WPF) 中,`WriteableBitmap` 是一个非常强大的类,它允许开发者直接对位图进行像素级别的操作。这个类是 `System.Windows.Media.Imaging` 命名空间的一部分,提供了灵活的方式来...
这个压缩包中的文件"dotnet 读 WPF 源代码笔记 WriteableBitmap 的渲染和更新是如何实现.md"显然是一份详细解析`WriteableBitmap`内部工作原理的学习资料,我们将在此基础上深入探讨`WriteableBitmap`的渲染和更新...
**WriteableBitmap类详解** 在Windows Presentation Foundation (WPF) 中,WriteableBitmap是一个非常重要的类,它提供了对位图的直接写入能力,允许开发者高效地进行像素级别的操作。这个类是System.Windows.Media...
在本文中,我们将深入探讨一个特定的WPF(Windows Presentation Foundation)问题,即当传入错误数据给WriteableBitmap时可能会导致渲染线程被锁住。这个问题在开发过程中需要特别注意,因为它可能严重影响应用程序...
本文档——“dotnet 读 WPF 源代码笔记 了解 WPF 已知问题 后台线程创建 WriteableBitmap 锁住主线程”——将深入探讨WPF的源代码分析,以及开发者在实际开发过程中可能遇到的问题,特别是关于后台线程创建...
在Windows Presentation Foundation (WPF) 和Windows Phone应用开发中,数据传输和图像处理常常涉及到文件、字节数组、流以及BitmapImage和WriteableBitmap对象之间的转换。这些转换在处理图像资源、保存用户数据...
在WPF中,我们可以利用`WriteableBitmap`类来对图像进行直接像素操作。`WriteableBitmap`继承自`BitmapSource`,允许我们以编程方式修改图像的每个像素。首先,你需要加载原始图片到`WriteableBitmap`对象: ```...
6. **使用WriteableBitmap**:对于复杂的动态图像,可以使用WriteableBitmap直接在内存中修改像素,然后将其显示在UI上,避免了WPF的图形管道开销。 7. **避免不必要的布局更新**:避免在UI线程上进行大量的计算,...
WriteableBitmap 类可用于所有 XAML 风格,包括 WPF、Windows 10 UWP、Windows Phone、WinRT Windows Store XAML 和 Silverlight。 它支持 .NET Framework 和 .NET Core 3,甚至被移植到 。 WriteableBitmapEx 允许...
私有 WPF 构建版本 当前的 WPF 在 [https://github.com/dotnet/wpf](https://github.com/dotnet/wpf) 完全开源,使用友好的 MIT 协议,意味着允许任何人任何组织和企业任意处置,包括使用,复制,修改,合并,发表,...
本文将深入探讨如何利用WPF中的WriteableBitmap对象来实现高效的图形绘制,并结合GDI+技术来操作像素,进一步提升性能。 WriteableBitmap是WPF中的一个类,它提供了一个可写的位图接口,允许我们直接访问像素数据...
`WriteableBitmap`是WPF提供的一种高性能的位图类,适用于动态更新图像内容,非常适合于这种一帧帧图片播放的需求。 首先,我们要理解`WriteableBitmap`的工作原理。`WriteableBitmap`继承自`BitmapSource`,可以...
图像亮度调整函数 `BrightnessAdjustProcess(WriteableBitmap src, int brightnessValue)` - **功能**:改变图像的整体亮度。 - **输入参数**:`src` - 原始图像对象;`brightnessValue` - 亮度值。 - **应用场景*...
WriteableBitmap wb_gray = new WriteableBitmap(wb.PixelWidth, wb.PixelHeight); ``` 然后,将灰度值转换为整数表示,并赋值给灰度图像: ```csharp byte[] GrayValueArr = new byte[4]; GrayValueArr[3] = 0xFF...
WriteableBitmap wb = new WriteableBitmap((BitmapSource)source); ``` 一旦我们有了WriteableBitmap对象,就可以访问并修改图像的每个像素。在C#中,可以使用锁像素方法来确保安全访问: ```csharp wb.Lock(); ...
其中一种常见方法是利用`System.Windows.Media.Imaging.WriteableBitmap`类,它可以捕获Silverlight控件的视觉树并将其转换为位图。 3. **WriteableBitmap** `WriteableBitmap` 是 Silverlight 中用于绘制像素的类...
2. **像素复制**:然后,使用`WriteableBitmap`的`CopyPixels()`方法,从原始`BitmapSource`复制像素到新的缩放后的`WriteableBitmap`。在这个过程中,可能需要进行插值运算以保持图像质量,尤其是当缩放比例不为...