天天看點

WPF技巧-Canvas轉為位圖

 在WPF中我們可以将Canvas當成一種畫布,将Canvas中的控件當成元素,講其轉成位圖檔案:

如下效果

WPF技巧-Canvas轉為位圖

                                                         圖1.1

       你可以設定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代碼中做處理:

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> 1 RenderTargetBitmap bmp = new RenderTargetBitmap(this.Screen.Width, this.Screen.Height, 96, 96, 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圖檔,如 

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代碼不變;

           效果如下:

WPF技巧-Canvas轉為位圖

         圖檔上出現一條黑塊,将此圖檔放入PHOTOSHOP中可看見居上偏移50為一透明塊,證明任何屬性的偏移對CANVAS的構圖都會造成影響。

         那麼直接在背景CS檔案中建一個CANVAS直接生成位圖是否可以?如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> 1 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);
RenderTargetBitmap bmp = new RenderTargetBitmap(cvs.Width, cvs.Height, 96, 96, 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 就可以生成一張位圖了。

           示例:

代碼

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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);

}

繼續閱讀