WPF,Silverlight与XAML读书笔记第三十 - 绘图系统概览

说明:本系列基本上是《WPF揭秘》的读书笔记。在结构安排与文章内容上参照《WPF揭秘》的编排,对内容进行了总结并加入一些个人理解。

 

    首先我们了解一下WPF作为新一代客户端技术的不同,在WPF之前客户端技术大都构建在GDI或GDI+基础之上,GDI,GDI+(另外包括像DirectX)这样的绘图技术属于立即模式图形系统。这种系统中图形可以被立即绘制到屏幕上,但我们也要负责维护这些绘制结果的可视状态,如,窗体由最小化恢复,由被其他程序覆盖到回到前段,窗体大小改变等发生时,我们要负责进行界面重绘。

    而WPF基于另一种称为保留模式的图形系统,这种模式下系统会记住绘制状态并维护它们,开发者无需担心绘制无效需要重绘的情况,这可以节省很大的工作量。总之WPF将DirectX的硬件加速与抗锯齿等能力与保留系统的易用性结合在一起。

研究WPF的绘图系统,我们可以分如下三个方面入手:

  • Drawing:指的是使用Brush对路径与形状进行填充或描边
  • Visual:Visual是把Drawing绘制到屏幕的一种方式,同时也提供无需依赖Drawing对象的底层轻量级实现
  • Shape:Shape是一些预制的Visual,可是把预制图形绘制到界面上最简单(也是最重量)的方法。

关于位图效果

位图效果虽然存在一定的性能问题,但其提供的如阴影效果、模糊效果,可以给WPF程序界面的视觉效果带来极大的提升。

 

Drawing是一个抽象类,这是我们本节所有2D图形的基类,WPF中包含5种Drawing的具体子类:

  • GeometryDrawing:其中包括Geemotry类,用于填充的Brush类,以及画轮廓的Pen类。
  • ImageDrawing:包括ImageSource类,以及用于定制边界的Rect类。
  • VideoBrush:包括MediaPlayer类及定义边界的Rect类。
  • GlyphRunDrawing:包括GlyphRun类,低层的文本类,绘制前景色的Brush类。
  • DrawingGroup:包含一组Drawing对象的集合,其属性用来批量改变其中包含的所有Drawing对象的属性(如透明度,变换)。DrawingGroup可以用在任意可以使用Drawing的地方,这两者的关系类似TransfromGroup与Transform的关系。

 

这其中GeometryDrawing将是我们主要研究的,其足以表示任何二维矢量图形,用于实现WPF版的剪切画,同时它也支持动画,数据绑定及资源引用。下面我们看一个GeometryDrawing类的例子,示例中定义了一个Pen,一个Geometry(描述椭圆的EllipseGeometry),以及一个Brush(前两者使用内容属性定义)

1 <GeometryDrawing Brush="Orange">

2     <GeometryDrawing.Pen>

3         <Pen Brush="Black" Thickness="10"/>

4     </GeometryDrawing.Pen>

5     <GeometryDrawing.Geometry>

6         <EllipseGeometry RadiusX="100" RadiusY="50"/>

7     </GeometryDrawing.Geometry>

8 </GeometryDrawing>

需要特别注意的,Drawing类并不是UIElement,其没有任何输出能力,要让Drawing对象得到渲染,我们可以将其放在如下3个宿主中的任意一个内。

  • DrawingImage:派生自ImageSource,可以在Image类(如BitmapImage类)中使用。如:
     1 <Image>
    
     2     <Image.Source>
    
     3         <DrawingImage>
    
     4             <DrawingImage.Drawing>
    
     5                 <GeometryDrawing>
    
     6                 </GeometryDrawing>
    
     7             </DrawingImage.Drawing>
    
     8         </DrawingImage>
    
     9     </Image.Source>
    
    10 </Image>
  • DrawingBrush:派生自Brush,可以应用到如Foreground,Background或控件的Border(通过BorderBrush)等地方。
     1 <TextBlock>
    
     2     <TextBlock.Background>
    
     3         <DrawingBrush>
    
     4             <DrawingBrush.Drawing>
    
     5                 <GeometryDrawing>                            
    
     6                 </GeometryDrawing>
    
     7             </DrawingBrush.Drawing>
    
     8         </DrawingBrush>
    
     9     </TextBlock.Background>
    
    10 </TextBlock>
  • DrawingVisual – 派生自Visual类

 

下面的XAML,展示了如何通过DrawingImage将前文展示的GeometryDrawing输出到屏幕上。(就是简单的将上文两段代码组合在一起)

 1 <Image>

 2     <Image.Source>

 3         <DrawingImage>

 4             <DrawingImage.Drawing>

 5                 <GeometryDrawing Brush="Orange">

 6                     <GeometryDrawing.Pen>

 7                         <Pen Brush="Black" Thickness="10"/>

 8                     </GeometryDrawing.Pen>

 9                     <GeometryDrawing.Geometry>

10                         <EllipseGeometry RadiusX="100" RadiusY="50"/>

11                     </GeometryDrawing.Geometry>

12                 </GeometryDrawing>

13             </DrawingImage.Drawing>

14         </DrawingImage>

15     </Image.Source>

16 </Image>

这段代码输出如下图形:

WPF,Silverlight与XAML读书笔记第三十 - 绘图系统概览

提示:DrawingImage与ImageDrawing

在文章的前面部分我们提到了这两个名称比较容易混淆的类DrawingImage和ImageDrawing。它们都可以混合显示基于矢量的和基于位图的内容。区别在于,DrawingImage是一种ImageSource,其能够把矢量图而非位图类型的东西作为其内容。而ImageDrawing是一种Drawing,其能把基于位图的ImageSource而不是矢量图作为其内容。

    几何体(Geometry)的使用场景大多是Drawing(如GeemetryDrawing,DrawingGroup),另外也有其他一些,如由Visual派生的类都提供了Clip属性,该属性接收Geometry对象,让你根据任意的形状(Geometry)来裁剪Visual对象。

 

本文完

 

参考:

《WPF揭秘》

你可能感兴趣的:(silverlight)