WPF实现XAML转图片的示例详解
黑夜中的潜行者 人气:0背景
在实际开发过程中,会遇到需要编写各类打印模板模板的需求,当然这些在WPF开发中更为常见,但是使用XAML写编辑的打印模板又不能直接发送给打印机进行打印,这个时候就需要将我们编写好的模板导出为可打印的文件,为什么选择了图片呢,是因为在众多文件格式中图片是最易于保存的,这点不仅凸显在临时保存更重要的是长期保存,我们知道图片可以使用Base64字符串、Byte字节在数据库中进行长期保存,为后期读取带来极大的便利,即使模板更新了,也可以打印出很久以前的文件样式。
在写代码实现的时候也参考了很多人的实现,基本都是使用Canvas一类的控件标签来实现的,这样弊端就很凸显了,那就是必须先示例模板对象,才能够获取到模板的 Size 简单来说就是在不预览的情况下是不能转出图片的。
实现思路
这里稍加改变将 Element 改成 Control 这个时候我们的思路就是先获取当前Control实例的排版再更新布局,然后我们写一个方法用来检索显示预览所需的大小。然后声明一个 RenderTargetBitmap 对象并设置一些基础参数来接收内存中的位图。选择想要的图片转换对象,保存即可。
这里做了一些扩展,将常用的图片类型列了出来,以便满足不同需求。
代码实现
using System; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; namespace XAMLToImage { public class Conversion { public static void GenerateImage(Control control, string imageType, string path) { using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate)) { GenerateImage(control, imageType, stream); stream.Flush(); stream.Close(); } } public static void GenerateImage(Control control, string imageType, Stream result) { if (control == null) return; control.InvalidateArrange(); control.UpdateLayout(); control.Background = Brushes.White; Size controlSize = RetrieveDesiredSize(control); Rect rect = new Rect(0, 0, controlSize.Width, controlSize.Height); RenderTargetBitmap bitmapRender = new RenderTargetBitmap((int)controlSize.Width, (int)controlSize.Height, 96, 96, PixelFormats.Pbgra32); control.Arrange(rect); bitmapRender.Render(control); BitmapEncoder encoder = null; //选取编码器 switch (imageType.ToUpper()) { case "BMP": encoder = new BmpBitmapEncoder(); break; case "GIF": encoder = new GifBitmapEncoder(); break; case "JPEG": encoder = new JpegBitmapEncoder(); break; case "PNG": encoder = new PngBitmapEncoder(); break; case "TIFF": encoder = new TiffBitmapEncoder(); break; default: break; } encoder.Frames.Add(BitmapFrame.Create(bitmapRender)); encoder.Save(result); } private static Size RetrieveDesiredSize(Control control) { control.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); return control.DesiredSize; } } }
可扩展
这里做一个小小的扩展,既然我们使用了Control作为模板,那么我们可以实现一个软件功能,就是将我们的模板统一使用XAML的Control来实现,然后导入我们的软件即可实现将设计好的模板、图形甚至是单界面原型将其导出。
加载全部内容