zoukankan      html  css  js  c++  java
  • 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);    
    }
  • 相关阅读:
    Best Time to Buy and Sell Stock III
    Valid Palindrome
    Longest Substring Without Repeating Characters
    Copy List with Random Pointer
    Add Two Numbers
    Recover Binary Search Tree
    Anagrams
    ZigZag Conversion
    Merge k Sorted Lists
    Distinct Subsequences
  • 原文地址:https://www.cnblogs.com/tmywu/p/1825650.html
Copyright © 2011-2022 走看看