• WPF技巧Canvas转为位图


          在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, 9696, 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, 9696, 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(00), 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, 9696, 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);    
    }
  • 相关阅读:
    P2351 [SDOI2012]吊灯
    洛谷P1450 [HAOI2008]硬币购物 背包+容斥
    P5110 块速递推-光速幂、斐波那契数列通项
    AT2304 Cleaning
    CSP-S 2020
    CF487E Tourists
    P4334 [COI2007] Policija
    动态逆序对专练
    CF437D The Child and Zoo
    CF1032G Chattering
  • 原文地址:https://www.cnblogs.com/tmywu/p/1825650.html
Copyright © 2020-2023  润新知