WPF Drawing 对象概述

Drawing 对象描述一些可见内容,例如形状、位图、视频或一行文本。 不同类型的 Drawing 描绘的是不同类型的内容。 下面列出了不同类型的 Drawing 对象。

Drawing 是一个通用对象;您可以通过多种方式使用 Drawing 对象。

WPF 提供了其他类型的对象,这些对象能够绘制形状、位图、文本和媒体。 例如,您也可以使用 Shape 对象绘制形状, MediaElement 控件提供了将视频添加到应用程序中的另一种方式。 那么,什么时候应使用 Drawing 对象? 当可以牺牲框架级别功能以获取性能优势或需要 Freezable 功能时。 由于 Drawing 对象缺少对 布局、输入和焦点的支持,因此它们具有性能优势,是描述背景、剪贴画以及使用 Visual 对象进行低级绘制的理想选择。

由于 Drawing 对象是一种类型为 Freezable 的对象,因此它们具有若干特殊功能,其中包括可声明为 资源、可在多个对象之间共享、可设为只读以提高性能、可进行克隆以及可设为线程安全对象。 有关 Freezable 对象提供的不同功能的更多信息,请参见 Freezable 对象概述

 
 
绘制形状

您可以使用 GeometryDrawing 来绘制形状。 几何绘图的 Geometry 属性描述要绘制的形状,其 Brush 属性描述形状内部的绘制方式,其 Pen 属性描述其轮廓的绘制方式。

下面的示例使用 GeometryDrawing 绘制形状。 该形状由 GeometryGroup 和两个 EllipseGeometry 对象进行描述。 形状内部使用 LinearGradientBrush 进行绘制,其轮廓则使用 Black  Pen 进行绘制。

本示例创建以下 GeometryDrawing

GeometryDrawing

两个椭圆的 GeometryDrawing
  1. //
  2. // Create the Geometry to draw.
  3. //
  4. GeometryGroup ellipses = new GeometryGroup();
  5. ellipses.Children.Add(
  6.     new EllipseGeometry(new Point(50,50), 4520)
  7.     );
  8. ellipses.Children.Add(
  9.     new EllipseGeometry(new Point(5050), 2045)
  10.     );
  11.  
  12.  
  13. //
  14. // Create a GeometryDrawing.
  15. //
  16. GeometryDrawing aGeometryDrawing = new GeometryDrawing();
  17. aGeometryDrawing.Geometry = ellipses;
  18.  
  19. // Paint the drawing with a gradient.
  20. aGeometryDrawing.Brush = 
  21.     new LinearGradientBrush(
  22.         Colors.Blue, 
  23.         Color.FromRgb(204,204,255), 
  24.         new Point(0,0), 
  25.         new Point(1,1));
  26.  
  27. // Outline the drawing with a solid color.
  28. aGeometryDrawing.Pen = new Pen(Brushes.Black, 10);
  29.  

<GeometryDrawing>
  <GeometryDrawing.Geometry>

    <!-- Create a composite shape. -->
    <GeometryGroup>
      <EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
      <EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
    </GeometryGroup>
  </GeometryDrawing.Geometry>
  <GeometryDrawing.Brush>

    <!-- Paint the drawing with a gradient. -->
    <LinearGradientBrush>
      <GradientStop Offset="0.0" Color="Blue" />
      <GradientStop Offset="1.0" Color="#CCCCFF" />
    </LinearGradientBrush>
  </GeometryDrawing.Brush>
  <GeometryDrawing.Pen>

    <!-- Outline the drawing with a solid color. -->
    <Pen Thickness="10" Brush="Black" />
  </GeometryDrawing.Pen>
</GeometryDrawing>

有关完整的示例,请参见 如何:创建 GeometryDrawing

使用其他 Geometry 类(例如 PathGeometry),您可以通过创建曲线和弧线来创建更复杂的形状。 有关 Geometry 对象的更多信息,请参见 Geometry 概述

有关不使用 Drawing 对象绘制形状的其他方法的更多信息,请参见 WPF 中的形状和基本绘图概述

 
 
绘制图像

您可以使用 ImageDrawing 绘制图像。 ImageDrawing 对象的 ImageSource 属性描述要绘制的图像,其 Rect 属性定义绘制图像的区域。

下面的示例将在一个矩形的 (75,75) 处绘制一个大小为 100 x 100 像素的图像。 下面的插图显示在示例中创建的 ImageDrawing 添加了一条灰色边框,以显示 ImageDrawing 的边界。

大小为 100 x 100 的 ImageDrawing

在 (75,75) 处绘制的 100 x 100 ImageDrawing
  1. // Create a 100 by 100 image with an upper-left point of (75,75). 
  2. ImageDrawing bigKiwi = new ImageDrawing();
  3. bigKiwi.Rect = new Rect(7575100100);
  4. bigKiwi.ImageSource = new BitmapImage(
  5.     new Uri(@"sampleImages\kiwi.png", UriKind.Relative));
  6.  

<!-- The Rect property specifies that the image only fill a 100 by 100
     rectangular area. -->
<ImageDrawing Rect="75,75,100,100" ImageSource="sampleImages\kiwi.png"/>

有关图像的更多信息,请参见 图像处理概述

播放媒体(仅限代码)
说明说明

虽然您可以在可扩展应用程序标记语言 (XAML) 中声明 VideoDrawing,但是只能使用代码加载并播放其媒体。 若要在可扩展应用程序标记语言 (XAML) 中播放视频,请改用 MediaElement

您可以使用 VideoDrawing MediaPlayer 来播放音频或视频文件。 加载并播放媒体的方法有两种。 第一种方法是使用 MediaPlayer VideoDrawing 自身,第二种方法是创建您自己的 MediaTimeline,并将其与 MediaPlayer VideoDrawing 一起使用。

说明说明

如果媒体随应用程序一起分发,则不能像图像那样将媒体文件用作项目资源。 在项目文件中,必须将媒体类型改设为 Content,并将 CopyToOutputDirectory 设置为 PreserveNewestAlways

若要在不创建自己的 MediaTimeline 的情况下播放媒体,请执行下列步骤。

  1. 创建 MediaPlayer 对象。

    1. MediaPlayer player = new MediaPlayer();
    2.  
  2. 使用 Open 方法加载媒体文件。

    1. player.Open(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));
    2.  
  3. 创建 VideoDrawing

    1. VideoDrawing aVideoDrawing = new VideoDrawing();
    2.  
  4. 通过设置 VideoDrawing Rect 属性指定要绘制媒体的大小和位置。

    1. aVideoDrawing.Rect = new Rect(00100100);
    2.  
  5. 使用您创建的 MediaPlayer 来设置 VideoDrawing Player 属性。

    1. aVideoDrawing.Player = player;
    2.  
  6. 使用 MediaPlayer Play 方法开始播放媒体。

    1. // Play the video once.
    2. player.Play();        
    3.  

下面的示例使用 VideoDrawing MediaPlayer 播放视频文件一次。

  1. //
  2. // Create a VideoDrawing.
  3. //      
  4. MediaPlayer player = new MediaPlayer();
  5.  
  6. player.Open(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));
  7.  
  8. VideoDrawing aVideoDrawing = new VideoDrawing();
  9.  
  10. aVideoDrawing.Rect = new Rect(00100100);
  11.  
  12. aVideoDrawing.Player = player;
  13.  
  14. // Play the video once.
  15. player.Play();        
  16.  
  17.  

若要对媒体进行更多的计时控制,请将 MediaTimeline MediaPlayer VideoDrawing 对象一起使用。 通过 MediaTimeline,您可以指定是否重复播放视频。 若要将 MediaTimeline VideoDrawing 一起使用,请执行下列步骤:

  1. 声明 MediaTimeline 并设置其计时行为。

    1. // Create a MediaTimeline.
    2. MediaTimeline mTimeline = 
    3.     new MediaTimeline(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative)); 
    4.  
    5. // Set the timeline to repeat.
    6. mTimeline.RepeatBehavior = RepeatBehavior.Forever;
    7.  
  2. MediaTimeline 创建 MediaClock

    1. // Create a clock from the MediaTimeline.
    2. MediaClock mClock = mTimeline.CreateClock();
    3.  
  3. 创建一个 MediaPlayer 并使用 MediaClock 设置其 Clock 属性。

    1. MediaPlayer repeatingVideoDrawingPlayer = new MediaPlayer();
    2. repeatingVideoDrawingPlayer.Clock = mClock;
    3.  
  4. 创建一个 VideoDrawing,并将 MediaPlayer 分配给 VideoDrawing Player 属性。

    1. VideoDrawing repeatingVideoDrawing = new VideoDrawing();
    2. repeatingVideoDrawing.Rect = new Rect(1500100100);
    3. repeatingVideoDrawing.Player = repeatingVideoDrawingPlayer;  
    4.  

下面的示例同时使用 MediaTimeline 以及 MediaPlayer VideoDrawing 来反复播放某视频。

  1. //
  2. // Create a VideoDrawing that repeats.
  3. //
  4.  
  5. // Create a MediaTimeline.
  6. MediaTimeline mTimeline = 
  7.     new MediaTimeline(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative)); 
  8.  
  9. // Set the timeline to repeat.
  10. mTimeline.RepeatBehavior = RepeatBehavior.Forever;
  11.  
  12. // Create a clock from the MediaTimeline.
  13. MediaClock mClock = mTimeline.CreateClock();
  14.  
  15. MediaPlayer repeatingVideoDrawingPlayer = new MediaPlayer();
  16. repeatingVideoDrawingPlayer.Clock = mClock;
  17.  
  18. VideoDrawing repeatingVideoDrawing = new VideoDrawing();
  19. repeatingVideoDrawing.Rect = new Rect(1500100100);
  20. repeatingVideoDrawing.Player = repeatingVideoDrawingPlayer;  
  21.  

请注意,使用 MediaTimeline 时,使用从 MediaClock Controller 属性返回的交互式 ClockController 控制媒体播放,而不是使用 MediaPlayer 的交互式方法。

绘制文本

您可以使用 GlyphRunDrawing GlyphRun 来绘制文本。 下面的示例使用 GlyphRunDrawing 来绘制文本“Hello World”。

  1. GlyphRun theGlyphRun = new GlyphRun(
  2.     new GlyphTypeface(new Uri(@"C:\WINDOWS\Fonts\TIMES.TTF")),
  3.     0,
  4.     false,
  5.     13.333333333333334,
  6.     new ushort[]{437279798235882857971},
  7.     new Point(012.29),
  8.     new double[]{
  9.         9.626666666666677.413333333333332.96
  10.         2.967.413333333333333.70666666666667
  11.         12.58666666666677.41333333333333
  12.         4.442.967.41333333333333},
  13.     null,
  14.     null,
  15.     null,
  16.     null,
  17.     null,
  18.     null
  19.  
  20.  
  21.     );
  22.  
  23. GlyphRunDrawing gDrawing = new GlyphRunDrawing(Brushes.Black, theGlyphRun);
  24.  

<GlyphRunDrawing ForegroundBrush="Black">
  <GlyphRunDrawing.GlyphRun>
    <GlyphRun 
      CaretStops="{x:Null}" 
      ClusterMap="{x:Null}" 
      IsSideways="False" 
      GlyphOffsets="{x:Null}" 
      GlyphIndices="43 72 79 79 82 3 58 82 85 79 71" 
      BaselineOrigin="0,12.29"  
      FontRenderingEmSize="13.333333333333334" 
      DeviceFontName="{x:Null}" 
      AdvanceWidths="9.62666666666667 7.41333333333333 2.96 2.96 7.41333333333333 3.70666666666667 12.5866666666667 7.41333333333333 4.44 2.96 7.41333333333333" 
      BidiLevel="0">
      <GlyphRun.GlyphTypeface>
        <GlyphTypeface FontUri="C:\WINDOWS\Fonts\TIMES.TTF" />
      </GlyphRun.GlyphTypeface>
    </GlyphRun>
  </GlyphRunDrawing.GlyphRun>
</GlyphRunDrawing>

GlyphRun 是低级别的对象,拟用于固定格式的文档表示和打印方案。 将文本绘制到屏幕上的一种比较简单的方法是使用 Label TextBlock 有关 GlyphRun 的更多信息,请参见 GlyphRun 对象和 Glyphs 元素简介概述。

复合绘图

使用 DrawingGroup,可将多个绘图组合为一个复合绘图。 使用 DrawingGroup,您可将形状、图像和文本组合到一个 Drawing 对象中。

下面的示例使用 DrawingGroup 将两个 GeometryDrawing 对象和一个 ImageDrawing 对象组合到一起。 该示例产生下面的输出。

复合绘图


具有多个绘图的 DrawingGroup

  1.             //
  2.             // Create three drawings.
  3.             //
  4.             GeometryDrawing ellipseDrawing =
  5.                 new GeometryDrawing(
  6.                     new SolidColorBrush(Color.FromArgb(10218124320)),
  7.                     new Pen(Brushes.Black, 4),
  8.                     new EllipseGeometry(new Point(50,50), 5050)
  9.                 );
  10.  
  11.             ImageDrawing kiwiPictureDrawing = 
  12.                 new ImageDrawing(
  13.                     new BitmapImage(new Uri(@"sampleImages\kiwi.png", UriKind.Relative)), 
  14.                     new Rect(50,50,100,100));
  15.  
  16.             GeometryDrawing ellipseDrawing2 =
  17.                 new GeometryDrawing(
  18.                     new SolidColorBrush(Color.FromArgb(102,181,243,20)),
  19.                     new Pen(Brushes.Black, 4),
  20.                     new EllipseGeometry(new Point(150150), 5050)
  21.                 );
  22.  
  23.             // Create a DrawingGroup to contain the drawings.
  24.             DrawingGroup aDrawingGroup = new DrawingGroup();
  25.             aDrawingGroup.Children.Add(ellipseDrawing);
  26.             aDrawingGroup.Children.Add(kiwiPictureDrawing);
  27.             aDrawingGroup.Children.Add(ellipseDrawing2);
  28.  
  29.  

<DrawingGroup>

  <GeometryDrawing Brush="#66B5F314">
    <GeometryDrawing.Geometry>
      <EllipseGeometry Center="50,50" RadiusX="50"  RadiusY="50"/>
    </GeometryDrawing.Geometry>
    <GeometryDrawing.Pen>
      <Pen Brush="Black" Thickness="4" />
    </GeometryDrawing.Pen>
  </GeometryDrawing>
  <ImageDrawing ImageSource="sampleImages\kiwi.png" Rect="50,50,100,100"/>
  <GeometryDrawing Brush="#66B5F314">
    <GeometryDrawing.Geometry>
      <EllipseGeometry Center="150,150" RadiusX="50"  RadiusY="50"/>
    </GeometryDrawing.Geometry>
    <GeometryDrawing.Pen>
      <Pen Brush="Black" Thickness="4" />
    </GeometryDrawing.Pen>
  </GeometryDrawing>
</DrawingGroup>

通过 DrawingGroup,您还可以对其内容应用不透明度蒙版、变换、位图效果及其他操作。 DrawingGroup 操作按下列顺序应用: OpacityMask Opacity BitmapEffect ClipGeometry GuidelineSet Transform

下图演示 DrawingGroup 操作的应用顺序。

DrawingGroup 操作的顺序


DrawingGroup 操作顺序

下表描述您可用于操作 DrawingGroup 对象内容的属性。

属性

说明

图示

OpacityMask

改变 DrawingGroup 内容选定部分的不透明度。 有关示例,请参见 How to: Control the Opacity of a Drawing

具有不透明遮罩的 DrawingGroup

Opacity

统一更改 DrawingGroup 内容的不透明度。 使用此属性将 Drawing 设置为透明或部分透明。 有关示例,请参见 How to: Apply an Opacity Mask to a Drawing

具有不同不透明度设置的 DrawingGroup

BitmapEffect

BitmapEffect 应用到 DrawingGroup 内容。 有关示例,请参见 How to: Apply a BitmapEffect to a Drawing

具有 BlurBitmapEffect 的 DrawingGroup

ClipGeometry

DrawingGroup 内容剪裁到您使用 Geometry 描述的区域内。 有关示例,请参见 How to: Clip a Drawing

具有定义的剪辑区域的 DrawingGroup

GuidelineSet

根据指定的准则将与设备无关的像素与设备像素对齐。 此属性有助于确保清晰地在 DPI 较低的显示器上呈现图形的细节。 有关示例,请参见 如何:向绘图应用 GuidelineSet

具有和没有 GuidelineSet 的 DrawingGroup

Transform

变换 DrawingGroup 内容。 有关示例,请参见 How to: Apply a Transform to a Drawing

旋转后的 DrawingGroup

使用 Drawing 绘制对象

DrawingBrush 是一种使用 Drawing 对象绘制区域的画笔。 您可以使用它来借助 Drawing 绘制任何图形对象。 DrawingBrush Drawing 属性描述其 Drawing 若要使用 DrawingBrush 呈现 Drawing,请使用画笔的 Drawing 属性将其添加到画笔中,并使用画笔绘制图形对象,例如控件或面板。

下面的示例使用从 GeometryDrawing 创建的图案通过 DrawingBrush 来绘制 Rectangle Fill 该示例产生下面的输出。

与 DrawingBrush 一起使用的 GeometryDrawing

平铺的 DrawingBrush
  1. using System;
  2. using System.Windows;
  3. using System.Windows.Controls;
  4. using System.Windows.Media;
  5. using System.Windows.Media.Animation;
  6. using System.Windows.Shapes;
  7.  
  8. namespace SDKSample
  9. {
  10.     public class DrawingBrushExample : Page
  11.     {
  12.  
  13.         public DrawingBrushExample()
  14.         {
  15.  
  16.             //
  17.             // Create the Geometry to draw.
  18.             //
  19.             GeometryGroup ellipses = new GeometryGroup();
  20.             ellipses.Children.Add(
  21.                 new EllipseGeometry(new Point(50,50), 4520)
  22.                 );
  23.             ellipses.Children.Add(
  24.                 new EllipseGeometry(new Point(5050), 2045)
  25.                 );
  26.  
  27.             //
  28.             // Create a GeometryDrawing.
  29.             //
  30.             GeometryDrawing aGeometryDrawing = new GeometryDrawing();
  31.             aGeometryDrawing.Geometry = ellipses;
  32.  
  33.             // Paint the drawing with a gradient.
  34.             aGeometryDrawing.Brush = 
  35.                 new LinearGradientBrush(
  36.                     Colors.Blue, 
  37.                     Color.FromRgb(204,204,255), 
  38.                     new Point(0,0), 
  39.                     new Point(1,1));
  40.  
  41.             // Outline the drawing with a solid color.
  42.             aGeometryDrawing.Pen = new Pen(Brushes.Black, 10);
  43.  
  44.             DrawingBrush patternBrush = new DrawingBrush(aGeometryDrawing);
  45.             patternBrush.Viewport = new Rect(000.250.25);
  46.             patternBrush.TileMode = TileMode.Tile;
  47.             patternBrush.Freeze();
  48.  
  49.             //
  50.             // Create an object to paint.
  51.             //
  52.             Rectangle paintedRectangle = new Rectangle();
  53.             paintedRectangle.Width = 100;
  54.             paintedRectangle.Height = 100;
  55.             paintedRectangle.Fill = patternBrush;
  56.  
  57.             //
  58.             // Place the image inside a border and
  59.             // add it to the page.
  60.             //
  61.             Border exampleBorder = new Border();
  62.             exampleBorder.Child = paintedRectangle;
  63.             exampleBorder.BorderBrush = Brushes.Gray;
  64.             exampleBorder.BorderThickness = new Thickness(1);
  65.             exampleBorder.HorizontalAlignment = HorizontalAlignment.Left;
  66.             exampleBorder.VerticalAlignment = VerticalAlignment.Top;
  67.             exampleBorder.Margin = new Thickness(10);
  68.  
  69.             this.Margin = new Thickness(20);
  70.             this.Background = Brushes.White;
  71.             this.Content = exampleBorder;
  72.         }
  73.     }
  74. }
  75.  

<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="PresentationOptions"
  Margin="20" Background="White">

  <Border BorderBrush="Gray" BorderThickness="1" 
    HorizontalAlignment="Left" VerticalAlignment="Top"
    Margin="10">
    <Rectangle Width="100" Height="100">
      <Rectangle.Fill>
        <DrawingBrush PresentationOptions:Freeze="True"
                      Viewport="0,0,0.25,0.25" TileMode="Tile">
          <DrawingBrush.Drawing>
            <GeometryDrawing>
              <GeometryDrawing.Geometry>
                <GeometryGroup>
                  <EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
                  <EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
                </GeometryGroup>
              </GeometryDrawing.Geometry>
              <GeometryDrawing.Brush>
                <LinearGradientBrush>
                  <GradientStop Offset="0.0" Color="Blue" />
                  <GradientStop Offset="1.0" Color="#CCCCFF" />
                </LinearGradientBrush>
              </GeometryDrawing.Brush>
              <GeometryDrawing.Pen>
                <Pen Thickness="10" Brush="Black" />
              </GeometryDrawing.Pen>
            </GeometryDrawing>
          </DrawingBrush.Drawing>
        </DrawingBrush>
      </Rectangle.Fill>

    </Rectangle>
  </Border>


</Page>

DrawingBrush 类提供了用于拉伸和平铺其内容的各种选项。 有关 DrawingBrush 的更多信息,请参见 使用图像、绘图和 Visual 进行绘制概述。

参考

概念

http://technet.microsoft.com/zh-cn/office/ms751619%28v=vs.110%29

原文地址:https://www.cnblogs.com/netuml/p/3058660.html