天天看點

WPF中如何使用圖像API進行繪制

原文: WPF中如何使用圖像API進行繪制

首先,由于WPF中不象GDI+中有Graphics對象,是以你無法使用Graphics進行繪圖了,取而代之的是:DrawingContext;類似地,GDI+中的OnPaint已被OnRender取代。

其次,UIElement有一個OnRendar方法,它的定義是:

protected virtual void OnRender (DrawingContext drawingContext)

但我們不能直接調用OnRender方法,也不能直接建立DrawingContext執行個體,但可以利用 DrawingGroup.Open 和DrawingVisual.RenderOpen。

這裡舉兩個例子:

(1)自定義繪制Canvas:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows;
using System.Globalization;

namespace BrawDraw.Com.Test
{
    class CanvasCustomPaint : Canvas
    {
        protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);
            //畫矩形
            dc.DrawRectangle(Brushes.Red, new Pen(Brushes.Blue, 1), 
                new Rect(new Point(20, 20), new Size(100, 100)));
            //畫文字
            dc.DrawText(new FormattedText("Hello, World!", CultureInfo.CurrentCulture, 
                FlowDirection.LeftToRight, new Typeface("Arial"), 40, Brushes.Orange),
                new Point(50,60));
        }
    }
}      

(2)儲存圖檔到檔案:

protected void SavePhoto(string fileName)
        {
            DrawingVisual drawingVisual = new DrawingVisual();
            DrawingContext drawingContext = drawingVisual.RenderOpen();
            // 畫矩形
            Rect rect = new Rect(new Point(160, 100), new Size(320, 80));
            drawingContext.DrawRectangle(Brushes.LightBlue, (Pen)null, rect);
            // 畫文字
            drawingContext.DrawText(
               new FormattedText("Hello, world",
                  CultureInfo.GetCultureInfo("en-us"),
                  FlowDirection.LeftToRight,
                  new Typeface("Verdana"),
                  36, Brushes.Black),
                  new Point(100, 60));

            drawingContext.Close();

            // 利用RenderTargetBitmap對象,以儲存圖檔
            RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)this.Width, (int)this.Height, 96, 96, PixelFormats.Pbgra32);
            renderBitmap.Render(drawingVisual);

            // 利用JpegBitmapEncoder,對圖像進行編碼,以便進行儲存
            JpegBitmapEncoder encoder = new JpegBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
            // 儲存檔案
            FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
            encoder.Save(fileStream);
            // 關閉檔案流
            fileStream.Close();
        }      

最後附上這裡的一段話(

http://blogs.msdn.com/timothyc/archive/2006/06/16/634638.aspx

),除加重點文字以桔色示凸出外, 以原樣提供:

Adding seemingly simple tweaks (e.g., clipping, bitmap effects) to our scene causes us to fall back to software, and software rending in WPF is slower than GDI+ software rendering.

First, the WPF software rendering code is derived from the GDI+ codebase. There are certain limits to what can be accomplished in hardware, and we have to work around what the hardware vendors give us.  As graphics hardware evolves, those limits are likely to become better over time.  If at least some portion of your scene is rendered in hardware, the cost of rendering is already going to be faster than it was in GDI+.  Finally, we shipped a tool at the PDC called ‘Perforator’ to help identify where software rendering occurs.

(注意紅色文字部分)

繼續閱讀