转自:http://www.cnblogs.com/tmywu/archive/2010/09/14/1825650.html

在WPF中我们可以将Canvas当成一种画布,将Canvas中的控件当成元素,讲其转成位图文件:

如下效果

图1.1

你可以设置Canvas的宽度、高度和颜色类型,生成任何你想要的图片。实时呈现你设置的样式等效果。

包括创建一些特效如阴影等。

   WPF提供RenderTargetBitmap类将任何容器控件渲染成一个位图。

新建一个WPF项目,在页面中创建一个CANVAS,如下:

1            <Canvas x:Name="Screen" Width="700" Height="200" Background="#F0CC0000">           
2                 <TextBlock Canvas.Left="200" Canvas.Top="50" x:Name="VSSize" text="Canvs 转换为图片"></TextBlock>               
3            </Canvas>

在CS代码中做处理:

RenderTargetBitmap bmp = new RenderTargetBitmap(this.Screen.Width, this.Screen.Height, , , PixelFormats.Pbgra32);
bmp.Render(this.Screen);
string file = @"c:\xxx.jpg";
string Extension = System.IO.Path.GetExtension(file).ToLower();
BitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
using (Stream stm = File.Create(file))
{
encoder.Save(stm);
}

这样就将CANVAS转换成图1.1的效果;

如果你对生成的图片有更高的清晰度的要求,你可以设置encoder的QualityLevel属性来改变JPEG的质量值,或者生成质量更高的PNG图片,如

1 encoder = new PngBitmapEncoder();            

我们改变下CANVAS的一些属性,将一个名为SCREEN的CANVAS 放在另一个CANVAS中并设置上偏移50,设置如下:

<Canvas>
 <Canvas Canvas.Top="50" x:Name="Screen" Width="700" Height="200" Background="#F0CC0000">           
      <TextBlock Canvas.Left="200" Canvas.Top="50" x:Name="VSSize" text="Canvs 转换为图片"></TextBlock>               
 </Canvas>
</Canvas>

后台CS代码不变;

效果如下:

图片上出现一条黑块,将此图片放入PHOTOSHOP中可看见居上偏移50为一透明块,证明任何属性的偏移对CANVAS的构图都会造成影响。

那么直接在后台CS文件中建一个CANVAS直接生成位图是否可以?如下:

Canvas cvs = new Canvas();
cvs.Width = ;
cvs.Height = ;
Label lb = new Label();
lb.content = "Canvas 转换为 图片";
Canvas.SetTop(lb,);
Canvas.Setleft(lb,);
cvs.child.add(lb);
RenderTargetBitmap bmp = new RenderTargetBitmap(cvs.Width, cvs.Height, , , PixelFormats.Pbgra32);
bmp.Render(cvs);
string file = @"c:\xxx.jpg";
string Extension = System.IO.Path.GetExtension(file).ToLower();
BitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
using (Stream stm = File.Create(file))
{
encoder.Save(stm);
}

运行代码,保存成的图像为一张700*200的空位图,说明直接在后台构造的容器无法直接转为位图。

解决办法:

RenderTargetBitmap.Render的对象为一个Visual对象,界面元素都继承自Visual对象。

我们可以建一个虚拟画布对象,如DrawingVisual drawingVisual = new DrawingVisual();

以此为基础使用DrawingContext对象将Canvas及其Child中的对象在DrawingVisual 虚画布上重新进行构图,然后Render DrawingVisual 就可以生成一张位图了。

示例:

Canvas cvs = new Canvas();
cvs.Width = ;
cvs.Height = ;
Label lb = new Label();
lb.content = "Canvas 转换为 图片";
Canvas.SetTop(lb,);
Canvas.Setleft(lb,);
cvs.child.add(lb); DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen(); //构造一个矩形
Rect rect = new Rect(new System.Windows.Point(, ), new System.Windows.Point(cvs.ActualWidth, cvs.ActualHeight));
//画一个矩形
drawingContext.DrawRectangle(cvs.Background, new System.Windows.Media.Pen(), rect);
//画文字
drawingContext.DrawText(new FormattedText(), new System.Windows.Point(Canvas.GetLeft(lb), Canvas.GetTop(lb))); drawingContext.Close(); RenderTargetBitmap bmp = new RenderTargetBitmap(cvs.Width, cvs.Height, , , PixelFormats.Pbgra32);
//Render DrawingVisual
bmp.Render(drawingVisual);
string file = @"c:\xxx.jpg";
string Extension = System.IO.Path.GetExtension(file).ToLower();
BitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
using (Stream stm = File.Create(file))
{
encoder.Save(stm);
}

WPF技巧-Canvas转为位图的更多相关文章

  1. Canvas动画 位图缓存提高效率和对应的内存问题

    对一个矢量图动画,开启位图缓存能大大提高运行效率.所谓开启位图缓存,其实要自己动手,先创建一个临时canvas,然后把矢量图绘制到这个canvas上,到了实际绘制时,直接把这个临时canvas拷贝到真 ...

  2. WPF Canvas转换为位图 (RenderTargetBitmap)

    使用 RenderTargetBitmap 的注意事项: 1. 要渲染的Canvas元素要放在Border元素内,并且此Border元素不能设置边框宽度(BorderThickness),不然生成的位 ...

  3. WPF在Canvas中绘图实现折线统计图

    最近在WPF中做一个需要实现统计的功能,其中需要用到统计图,之前也没有接触过,度娘上大多都是各种收费或者免费的第三方控件,不想用第三方控件那就自己画一个吧. 在园子还找到一篇文章,思路来自这篇文章,文 ...

  4. Wpf 之Canvas介绍

    从这篇文章开始是对WPF中的界面如何布局做一个较简单的介绍,大家都知道:UI是做好一个软件很重要的因素,如果没有一个漂亮的UI,功能做的再好也无法吸引很多用户使用,而且没有漂亮的界面,那么普通用户会感 ...

  5. WPF 中Canvas图形移动、缩放代码

    从Flash转C#,很多内容一知半解,边摸索边前进,代码粗糙,权当留个脚印. 只是想得到一个基础的移动和缩放功能的界面,找了很久都是画线.画矩形等基础形状的代码,移动和缩放说的并不清晰,只能自己努力来 ...

  6. wpf,vb,位图剪裁的方法

    ‘ 貌似WPF对GDI+不提供支持,要达到剪裁图像的方法,可以使用image.clip,’不过clip只是对图片的一个遮挡拦截效果,并不改变本身的图片资源.‘下面的代码提供了剪裁图片资源的方法. Di ...

  7. WPF使用Canvas绘制可变矩形

    1.问题以及解决办法 最近因为项目需要,需要实现一个位置校对的功能,大致的需求如下:有一个图片,有一些位置信息,但是位置信息可能和实际有些偏差,需要做简单调整,后面会对这张图片进行切割等,做些处理.( ...

  8. WPF中Canvas使用

    首先知道Canvas有Left.Right.Top和Bottom这四个属性,放入Canvas的元素通过这四个属性来决定它们在Canvas里面的位置. 比如: Xaml: <Canvas Hori ...

  9. WPF技巧:命中测试在视觉树中的使用

    我们有时候又需求从当前视觉树中找一些东西,比如鼠标按下的时候,看看鼠标下的元素都有什么.又比如某块区域下有哪些元素?某个坐标点下有哪些元素? 这些需求在使用 命中测试的时候,可以非常方便和快速的去找到 ...

随机推荐

  1. RGui的http代理设置

    办公电脑环境需要http代理访问大网,使用R语言安装包时老是无法连接网络,后来从网上发现解决方法很简单,只需在启动RGui.exe的命令行上加上启动参数就可以了. "C:\Program F ...

  2. 一个基于Myeclipse开发的Java打地鼠小游戏(Appletcation)

    package javaes.zixue.wangshang.daima; 2 3 import java.awt.Cursor; import java.awt.Image; import java ...

  3. IOS 杂笔-3 (property参数)

    (1)内存管理相关参数 Retain:对对象release旧值,retain新值(适用于OC对象类型) Assign:直接赋值(默认,适用于非oc对象类型) Copy:release旧值,copy新值 ...

  4. IOS之UIImageView--小实例项目--带音效的拳皇动画

    内容大纲: 1.初步工作 2.开始敲代码 3.注意 4.可能遇到的错误 5.设置音频速率在代码顺序上的注意点 带音效的拳皇动画实例项目 初步工作 1.新建一Objective-C工程之后,将需要的拳皇 ...

  5. eclipse执行单元测试报CreateProcess error=87的解决方法

    原因是classpath的路径过长导致,在网上看了很多文章,发现解决方法有2种: 1.更改项目路径 或者 maven本地库的路径,减少classpath的深度. 2.由于这是eclipse自身的bug ...

  6. java 的方法注释写在哪里?

    如果有接口,写在接口方法上即可.鼠标滑过方法名时时会显示 如果没有接口,写在每个方法上方. eclipse 分三步 ① 找到方法,并将光标移动至方法名的上方 ②/** ③回车 那,效果是酱紫

  7. ajax跨域 自定义header问题总结

    遇到的问题:已经在ajax里面添加自定义参数,但是没有生效 beforeSend : function(request) { request.setRequestHeader("region ...

  8. 对Jena的简单理解和一个例子

    本文简单介绍Jena(Jena 2.4),使用Protégé 3.1(不是最新版本)创建一个简单的生物(Creature)本体,然后参照Jena文档中的一个例子对本体进行简单的处理,输出本体中的Cla ...

  9. 树形dp--hdu 3534 Tree

    Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  10. Linux系统之用户、群组和权限

    一.用户管理 创建用户时,系统为用户分配一个唯一的编号UID,同时为用户创建一个同名的组,并为组分配一个编号GID,并把该用户加入该组中. 系统规定: uid: 0       特权用户      u ...