转自: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. 转:纠结的Shim

    原文地址:http://www.haorooms.com/post/requirejs_sy_lj RequireJs已经流行很久了,它提供了以下功能: 声明不同js文件之间的依赖 可以按需.并行.延 ...

  2. 桥牌笔记L4D17:小心阻塞

    南打3NT. 西的首攻会有3墩黑桃.3墩方块.2付梅花,共8墩到手.看来方块如果3-2分布的话,非常容易就能超一完成. 所以要想着4-1分布的安全打法. 第一墩庄家拿了黑桃J后,明手的黑桃A会阻塞,庄 ...

  3. 主程序底部TabBar功能跟登录页面布局

    1:主程序底部TabBar的功能实现 效果图: 主要代码如下: - (UITabBarController*)setRootVC:(BOOL)bShowCart { //创建一个子控制器 用于显示当前 ...

  4. 安卓第十天笔记-fragment

    安卓第十天笔记-fragment Fragment(片段) 一.Fragment简介 *Fragment是3.0引入的API,主要为了解决平板,大屏幕手机显示问题 *Fragment代表了Activi ...

  5. android 音乐播放器简单实现

    package com.zhangbz.musicplayer; import java.io.File; import android.app.Activity; import android.me ...

  6. vs(vistual studio)项目文件名字重复问题

    今天遇到一情况,比较神奇,vs项目,我更新SVN的时候,发现竟然出现文件名字重复的现象. [caption id="" align="alignnone" wi ...

  7. css中font-family的中文字体

    说到css中的font-family,相信很多朋友经常用,但不知道当你遇到引用中文字体的时候你会怎么写?最近特别关注了下,发现最常用的基本有三种类型: 1.直接中文: 2.英文形式: 3.unicod ...

  8. TCP & UDP & IP

    TCP和UDP的区别   TCP UDP 是否连接 面向连接 面向非连接 应用场合 可靠的 不可靠的 速度 慢 快 传送数据 字节流 数据报 是否可用于广播 否 是 为什么UDP比TCP快 不需要连接 ...

  9. swipe js dynamic content

    swipe js dynamic content swipe 动态改变内容时,需要用 update 一下. swiper.update(true); 实例: HTML Code  页面用的FreeMa ...

  10. [VMware]设置VM虚拟机随系统自动启动

    设置步骤: 1.找到VM的安装路径,右键vmware发送到桌面快捷方式 2.右键桌面快捷方式的属性,看到目标的属性框 3.找到需要自启动的虚拟机路径,如: D:\QC_VM\Clone of Wind ...