簡介:
之前有講到過微軟的GDI+技術(shù),這個大多數(shù)是在WinForm上使用的,而在WPF中用到最多的就是DrawingContext技術(shù)了。
DrawingContext是一個抽象類,不能直接創(chuàng)建類的實例。而且也不能創(chuàng)建它的子類(因為它沒有公開的構(gòu)造函數(shù))。要創(chuàng)建DrawingContext對象,有兩種方式:
- 使用類的方法
// DrawingVisual.RendOpen()方法
DrawingVisual dv = new DrawingVisual();
using DrawingContext context = dv.RenderOpen();
context.DrawXX(...); // 繪制圖形
// DrawingGroup.Open()方法
DrawingGroup dg = new DrawingGroup();
using DrawingContext dc = dg.Open();
dc.DrawXX(...); // 繪制圖形
- 繼承自UIElement類
public class visualElement:UIElement
{
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
}
}
畫圖:
DrawingContext類提供了很多的方法,比如畫線,畫圓等,這里就不一一列舉了,感興趣的可以去看下微軟官網(wǎng)對DrawingContext類的介紹。這里我們就簡單畫線做示例:
- DrawingVisual
private void DrawingVisualTest()
{
//輕量級視覺對象,用于高效繪制單次渲染的矢量圖形(如動態(tài)生成內(nèi)容)。
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
Pen pen = new()
{
Thickness = 3,
Brush = new SolidColorBrush(Colors.Red)
};
dc.DrawRectangle(null, new Pen(Brushes.Blue, 2), new Rect(0, 0, 298, 298));
dc.DrawLine(pen, new Point(0, 0), new Point(150, 150));
// 改成虛線,上面也會改的,如果只想該下面,就重新new一個pen
pen.DashStyle = DashStyles.Dash;
//dc.DrawLine(pen, new Point(0, 150), new Point(150, 150));
LineGeometry line = new LineGeometry(new Point(0, 150), new Point(150, 150));// 無需額外對象,內(nèi)存占用極低。
dc.DrawGeometry(null, pen, line);//需預先創(chuàng)建 Geometry 對象,可能增加內(nèi)存開銷(但可復用)。null 表示不填充內(nèi)部(僅描邊)
}
//DrawingContext不是一個Visual對象,而僅僅只是一個繪圖環(huán)境,繪制的圖形僅保存在系統(tǒng)中。如果要顯示出來,就必須將其轉(zhuǎn)換為Visual對象。
// 將 DrawingVisual 的內(nèi)容轉(zhuǎn)換為 DrawingImage
DrawingImage drawingImage = new DrawingImage(dv.Drawing);
img.Source = drawingImage;
}
- DrawingGroup
private void DrawingGroupTest()
{
//組合多個 Drawing 對象,形成邏輯分組,便于統(tǒng)一管理、變換或共享屬性。
DrawingGroup group = new DrawingGroup();
using (DrawingContext dc = group.Open())
{
Pen pen = new()
{
Thickness = 3,
Brush = new SolidColorBrush(Colors.Red),
//DashStyle = DashStyles.Dash, // 設置為虛線樣式
};
// 或者這樣也可以
//Pen pen = new Pen(Brushes.White, 1);
//pen.DashStyle = DashStyles.Dash;
// 先畫一個矩形,告訴坐標系0,0位置,如果不這樣就需要在xaml中設置對齊方式,就是水平和垂直方式(控件默認是居中)
// 設置image對其方式如果為top和left 那么左上角就是0,0坐標系,如果是bottom和right 那么右下角就是0,0坐標系
dc.DrawRectangle(null, new Pen(Brushes.Blue, 2), new Rect(0, 0, 298, 298));
dc.DrawLine(pen, new Point(0, 0), new Point(0, 150));
dc.DrawLine(pen, new Point(0, 150), new Point(150, 150));
//group.Transform = new RotateTransform(45); // 整體旋轉(zhuǎn)45度
}
//DrawingContext不是一個Visual對象,而僅僅只是一個繪圖環(huán)境,繪制的圖形僅保存在系統(tǒng)中。如果要顯示出來,就必須將其轉(zhuǎn)換為Visual對象。
// 將 DrawingVisual 的內(nèi)容轉(zhuǎn)換為 DrawingImage
DrawingImage drawingImage = new DrawingImage(group);
img.Source = drawingImage;
}
Geometry(幾何)和Shape(形狀)
- Geometry:
.Net中,Geometry類就是用于描述這種幾何圖形的類。它只包含描述幾何圖形的必要屬性,并提供包括命中測試、動畫等功能。它派生出以下七個類,以簡化對圖形的描述:
| 類名 | 功能 |
|---|---|
| LineGeometry | 直線 |
| EllipseGeometry | 橢圓(圓也是橢圓的一種) |
| RectangleGeometry | 矩形 |
| PathGeometry | 路線(類似與隨手畫的一條任意線) |
| GeometryGroup | 幾何圖形組(把多個幾何圖形放在一起) |
| CombinedGeometry | 組合圖形(將多個幾何圖形做布爾運算) |
| StreamGeometry | 它是PathGeometry的輕量級對象 |
- Shape:
形狀(Shape),就是一個能看得到的幾何圖形。例如我們在白紙上,用紅色的筆畫一條直線,一個矩形。
由此可見,Shape的本質(zhì),就是在幾何圖形(Geometry)的基礎上,加上畫筆,顏色等信息,繪制而成。
.Net中,Shape就是表示“形狀”的類。它是一個抽象類,繼承自FrameworkElement,這意味著它是一個元素,可以直接顯示在窗體上。
| 類型 | 功能 |
|---|---|
| Ellipse | 橢圓形 |
| Line | 直線 |
| Path | 路徑 |
| Polygon | 多邊形 |
| Polyline | 多段線 |
| Rectangle | 矩形 |
使用圖元轉(zhuǎn)換器繪制圖形
上面的例子中我們看到繪制的圖形需要通過將 DrawingVisual 的內(nèi)容轉(zhuǎn)換為 DrawingImage才能賦值顯示。這就牽涉到了圖元轉(zhuǎn)換或包裝。
- 圖元包裝器:Drawing
Drawing類用于包裝2D圖元(圖元可以是Geometry,也可以是GlyphRun、Image、Video),并為其添加一些額外的信息,比如Pen,Brush等屬性。它是一個抽象類,可以使用它的派生類來包裝不同的圖形:
| 類名 | 功能 |
|---|---|
| GeometryDrawing | 包裝幾何圖形 |
| GlyphRunDrawing | 包裝字符 |
| ImageDrawing | 包裝圖片 |
| VideoDrawing | 包裝視頻 |
| DrawingGroup | 將多個Drawing對象組合到一個繪圖器中,進行統(tǒng)一包裝 |
- 圖元轉(zhuǎn)換器:DrawingXX
| 類名 | 功能 |
|---|---|
| DrawingBrush | 將Drawing對象當成畫刷。類似與Photoshop中的畫刷功能 |
| DrawingImage | 將Drawing對象當成ImageSource。 |
DrawingBrush:
DrawingBrush的作用是將Drawing對象轉(zhuǎn)換為Brush。在任何需要用到Brush的地方,就可以使用它。
// 創(chuàng)建幾何圖形
EllipseGeometry cicle = new(new Point(5, 5), 5, 5);
EllipseGeometry cicle2 = new(new Rect(new Size(20, 16)));
GeometryGroup geoGroup = new() { Children = { cicle, cicle2 }, FillRule= FillRule.EvenOdd };
// 創(chuàng)建圖畫
GeometryDrawing drawing = new(Brushes.Red, new Pen(Brushes.Blue, 2), geoGroup);
// 創(chuàng)建DrawingBrush
DrawingBrush brushes = new DrawingBrush(drawing);
border.BorderThickness = new Thickness(50);
border.Background = brushes;
DrawingImage:
DrawingImage的作用是把Drawing對象轉(zhuǎn)換為ImageSource。在任何需要ImageSource的地方,就可以使用它。
// 創(chuàng)建幾何圖形
EllipseGeometry cicle = new(new Point(5, 5), 5, 5);
EllipseGeometry cicle2 = new(new Rect(new Size(20, 16)));
GeometryGroup geoGroup = new() { Children = { cicle, cicle2 }, FillRule= FillRule.EvenOdd };
// 創(chuàng)建圖畫
GeometryDrawing drawing = new(Brushes.Red, new Pen(Brushes.Blue, 2), geoGroup);
// 創(chuàng)建DrawingBrush
DrawingBrush brushes = new DrawingBrush(drawing);
DrawingImage image = new(drawing);
img.Source = image;