zoukankan      html  css  js  c++  java
  • 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>

    这段代码输出如下图形:

    提示:DrawingImage与ImageDrawing

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

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

    本文完

    参考:

    《WPF揭秘》

  • 相关阅读:
    正则表达式之re模块
    collections模块
    openpyxl模块
    hashlib模块
    random模块
    os模块
    sys模块
    nodeType
    数据类型转换
    添加删除
  • 原文地址:https://www.cnblogs.com/lsxqw2004/p/4627720.html
Copyright © 2011-2022 走看看