原址: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代码中做处理:
1
RenderTargetBitmap bmp
=
new
RenderTargetBitmap(
this
.Screen.Width,
this
.Screen.Height,
96
,
96
, PixelFormats.Pbgra32);
2
bmp.Render(
this
.Screen);
3
string
file
=
@"
c:\xxx.jpg
"
;
4
string
Extension
=
System.IO.Path.GetExtension(file).ToLower();
5
BitmapEncoder encoder
=
new
JpegBitmapEncoder();
6
encoder.Frames.Add(BitmapFrame.Create(bmp));
7
using
(Stream stm
=
File.Create(file))
8
{
9
encoder.Save(stm);
10
}
这样就将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直接生成位图是否可以?如下:
1
Canvas cvs
=
new
Canvas();
2
cvs.Width
=
700
;
3
cvs.Height
=
200
;
4
Label lb
=
new
Label();
5
lb.content
=
"
Canvas 转换为 图片
"
;
6
Canvas.SetTop(lb,
50
);
7
Canvas.Setleft(lb,
200
);
8
cvs.child.add(lb);
9
RenderTargetBitmap bmp
=
new
RenderTargetBitmap(cvs.Width, cvs.Height,
96
,
96
, PixelFormats.Pbgra32);
10
bmp.Render(cvs);
11
string
file
=
@"
c:\xxx.jpg
"
;
12
string
Extension
=
System.IO.Path.GetExtension(file).ToLower();
13
BitmapEncoder encoder
=
new
JpegBitmapEncoder();
14
encoder.Frames.Add(BitmapFrame.Create(bmp));
15
using
(Stream stm
=
File.Create(file))
16
{
17
encoder.Save(stm);
18
}
运行代码,保存成的图像为一张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);
}