WPF技巧-Canvas转为位图

转自: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, 96, 96, 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 = 700;
cvs.Height = 200;
Label lb = new Label();
lb.content = "Canvas 转换为 图片";
Canvas.SetTop(lb,50);
Canvas.Setleft(lb,200);
cvs.child.add(lb);
RenderTargetBitmap bmp = new RenderTargetBitmap(cvs.Width, cvs.Height, 96, 96, 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 = 700;
cvs.Height = 200;
Label lb = new Label();
lb.content = "Canvas 转换为 图片";
Canvas.SetTop(lb,50);
Canvas.Setleft(lb,200);
cvs.child.add(lb);

DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();

//构造一个矩形
Rect rect = new Rect(new System.Windows.Point(0, 0), 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, 96, 96, 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);
}
时间: 2024-08-05 06:41:14

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

WPF使用Canvas绘制可变矩形

1.问题以及解决办法 最近因为项目需要,需要实现一个位置校对的功能,大致的需求如下:有一个图片,有一些位置信息,但是位置信息可能和实际有些偏差,需要做简单调整,后面会对这张图片进行切割等,做些处理.(位置信息连接起来是一个个小矩形.) 解决以上问题的大致思路如下:使用canvas进行绘制,把图片作为canvas的背景,在canvas上绘制矩形,类似于qq截图一样,矩形框可以使用鼠标拖动调整大小.然后在记下修改后的位置,提供给后面切割图片使用.目前的关键问题就是实现类似qq截图那样可以拖动的矩形.

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

对一个矢量图动画,开启位图缓存能大大提高运行效率.所谓开启位图缓存,其实要自己动手,先创建一个临时canvas,然后把矢量图绘制到这个canvas上,到了实际绘制时,直接把这个临时canvas拷贝到真正canvas上.而位图拷贝的速度是非常快的,比重新绘制矢量图要快很多. 三部曲: 1.建立临时canvas(位图缓存) p.cache = function(x, y, width, height, scale) { // draw to canvas. scale = scale||1; if

WPF Canvas转换为位图 (RenderTargetBitmap)

使用 RenderTargetBitmap 的注意事项: 要渲染的Canvas元素要放在Border元素内,并且此Border元素不能设置边框宽度(BorderThickness),不然生成的位图会出现错误.如果需要边框效果,可再加一层Border. 例: cs: RenderTargetBitmap bmp = new RenderTargetBitmap((int)canvas.ActualWidth, (int)canvas.ActualHeight, 96, 96, PixelForma

wpf,vb,位图剪裁的方法

‘ 貌似WPF对GDI+不提供支持,要达到剪裁图像的方法,可以使用image.clip,’不过clip只是对图片的一个遮挡拦截效果,并不改变本身的图片资源.‘下面的代码提供了剪裁图片资源的方法. Dim path = "C:\Users\Administrator\Desktop\image\image\Images\tori_gaku_02.png" Dim bitmap As BitmapSource = New BitmapImage(New Uri(path, UriKind.

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

从Flash转C#,很多内容一知半解,边摸索边前进,代码粗糙,权当留个脚印. 只是想得到一个基础的移动和缩放功能的界面,找了很久都是画线.画矩形等基础形状的代码,移动和缩放说的并不清晰,只能自己努力来解决一下. 素材准备: WPF项目的屏幕上放一个Canvas控件,名称为canvas1. 代码如下: 1 using System; 2 using System.Windows; 3 using System.Windows.Media; 4 using System.Windows.Input;

移动端图片优化技巧 canvas代替image

通常来讲,移动端展示一张图片是用浏览器来渲染的,如果图片过大,手机性能不太好的情况下,手机会显示比较卡. 原因是没有处罚设备本身的GPU来渲染,可以使用canvas触发GPU来渲染图片. 使用 drawImage()方法 如: var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); var img= new Image();img.src = url;img.onload = fu

WPF技巧 n问

问一:Popup控件Placement属性设置固定值后,在不同的电脑可能有不同行为的问题 Popup.Placement属性受SystemParameters.MenuDropAlignment(该值指示弹出菜单相对于相应菜单项是左对齐还是右对齐.)属性的影响,你可以这么设置: if (SystemParameters.MenuDropAlignment) { Popup.Placement = PlacementMode.Left; } else { Popup.Placement = Pla

【WPF学习】第五十二章 动画性能

通常,为用户界面应用动画只不过是创建并配置正确的动画和故事板对象.但在其他情况下,特别是同时发生多个动画时,可能需要更加关注性能.特定的效果更可能导致这些问题——例如,那些涉及视频.大位图以及多层透明等的效果通常需要占用更多CPU开销.如果不谨慎实现这类效果,运行它们使可能造成明显抖动,或者会从其他同时运行的应用程序抢占CPU时间. 幸运的是,WPF提供了几个可提供帮助的技巧.接下来的几节将学习降低最大帧率以及缓存计算机显卡中的位图,这两种技术可以减轻CPU的负担. 一.期望的帧率 正如前面所学

[Aaronyang]谈谈2015年AY对WPF全面技术总结,AYUI来了

         原著:AY WPF博客- 把wpf推广出去,让那些鄙视的人说不 大家好! 我是AY,首先声明,我在做一件很枯燥的事情,我是个91后程序员,每天熬夜完成计划的过着下班后的生活. 那天有人反对,那天有人安慰,那天有人嘲讽,那天有人祝福. 过了6个月后,我对自己的梦想一直没有改变过,继续坚持,终于,AYUI诞生了. 今天有人说造轮子,今天有人说你好厉害,今天有人说开源吗? 有人说好喜欢... 有贬有褒,但是好的声音多了. 但是身体的各种问题也来了.. AY提供的WPF书籍下载: 下载