WPF技巧-Canvas转为位图

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

                        

你可以设置Canvas的宽度、高度和颜色类型,生成任何你想要的图片。实时呈现你设置的样式等效果,包括创建一些特效如阴影等。

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

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

<Canvas x:Name="Screen" Width="700" Height="200" Background="#F0CC0000">           
<TextBlock Canvas.Left="200" Canvas.Top="50" x:Name="VSSize" text="Canvs 转换为图片"></TextBlock>               
</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 }            
复制代码

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

1 encoder = new PngBitmapEncoder();            

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

1
2
3
4
5
<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 就可以生成一张位图了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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);   
 }

  

 

posted @   多见多闻  阅读(584)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示