画笔转换概述

Brush 类提供两个转换属性:TransformRelativeTransform。 使用这些属性,可以旋转、缩放、倾斜和转换画笔的内容。 本主题介绍这两个属性之间的区别,并提供有关它们的用法示例。

先决条件

若要了解本主题,应了解要转换的画笔的功能。 有关 LinearGradientBrushRadialGradientBrush,请参阅使用纯色和渐变进行绘制概述。 有关 ImageBrushDrawingBrushVisualBrush,请参阅使用图像、绘图和视觉对象进行绘制。 还应当熟悉转换概述中所述的 2D 转换。

Transform 和 RelativeTransform 属性之间的区别

将转换应用到画笔的 Transform 属性时,如果要围绕其中心转换画笔内容,则需要知道已绘制区域的大小。 假设已绘制区域的宽度为 200 个与设备无关的像素,高度为 150。 如果已使用 RotateTransform 将画笔的输出围绕其中心旋转 45 度,将为 RotateTransform 指定 100 的 CenterX 和 75 的 CenterY

将转换应用到画笔的 RelativeTransform 属性时,在其输出映射到已绘制区域之前将该转换应用到画笔。 以下列表介绍处理和转换画笔内容的顺序。

  1. 处理画笔的内容。 对于 GradientBrush,这意味着确定渐变区域。 对于 TileBrushViewbox 将映射到 Viewport。 这成为画笔的输出。

  2. 将画笔的输出投影到 1 x 1 的转换矩形上。

  3. 应用画笔的 RelativeTransform(如果有)。

  4. 将转换后的输出投影到要绘制的区域上。

  5. 应用画笔的 Transform(如果有)。

由于在画笔输出映射到 1 x 1 的矩形时应用了 RelativeTransform,因此转换中心和偏移值看起来是相对的。 例如,如果已使用 RotateTransform 将画笔的输出围绕其中心旋转 45 度,将为 RotateTransform 指定 0.5 的 CenterX 和 0.5 的 CenterY

下图显示已使用 RelativeTransformTransform 属性旋转 45 度的多个画笔的输出。

RelativeTransform and Transform properties

将 RelativeTransform 用于 TileBrush

由于平铺画笔比其他画笔更复杂,因此将 RelativeTransform 应用到平铺画笔可能产生意外的结果。 例如以下图像。

The source image

以下示例使用 ImageBrush 绘制带有上述图像的矩形区域。 它将 RotateTransform 应用到 ImageBrush 对象的 RelativeTransform 属性,并将其 Stretch 属性设置为 UniformToFill,这应当在图像拉伸以完全填充矩形时保留图像的纵横比。

<Rectangle Width="200" Height="100" Stroke="Black" StrokeThickness="1">
  <Rectangle.Fill>
    <ImageBrush Stretch="UniformToFill">
      <ImageBrush.ImageSource>
        <BitmapImage UriSource="sampleImages\square.jpg" />
      </ImageBrush.ImageSource>
      <ImageBrush.RelativeTransform>
        <RotateTransform CenterX="0.5" CenterY="0.5" Angle="90" />
      </ImageBrush.RelativeTransform>
    </ImageBrush>
  </Rectangle.Fill>
</Rectangle>

该示例产生下面的输出:

The transformed output

请注意,即使画笔的 Stretch 已设置为 UniformToFill,图像也会扭曲。 这是因为在将画笔的 Viewbox 映射到 Viewport 之后,应用了相对转换。 以下列表介绍该过程的每个步骤:

  1. 使用画笔的 Stretch 设置将画笔的内容 (Viewbox) 投影到其基本图块上 (Viewport)。

    Stretch the Viewbox to fit the Viewport

  2. 将基本图块投影到 1 x 1 的转换矩形上。

    Map the Viewport to the transformation rectangle

  3. 应用 RotateTransform

    Apply the relative transform

  4. 将转换后的基本图块投影到要绘制的区域上。

    Project the transformed brush onto the output area

示例:将 ImageBrush 旋转 45 度

以下示例将 RotateTransform 应用于 ImageBrushRelativeTransform 属性。 CenterY 对象的 RotateTransformCenterX 属性均设置为 0.5,即内容中心点的相对坐标。 因此,画笔的内容围绕其中心旋转。

//
// Create an ImageBrush with a relative transform and
// use it to paint a rectangle.
//
ImageBrush relativeTransformImageBrush = new ImageBrush();
relativeTransformImageBrush.ImageSource =
    new BitmapImage(new Uri(@"sampleImages\pinkcherries.jpg", UriKind.Relative));

// Create a 45 rotate transform about the brush's center
// and apply it to the brush's RelativeTransform property.
RotateTransform aRotateTransform = new RotateTransform();
aRotateTransform.CenterX = 0.5;
aRotateTransform.CenterY = 0.5;
aRotateTransform.Angle = 45;
relativeTransformImageBrush.RelativeTransform = aRotateTransform;

// Use the brush to paint a rectangle.
Rectangle relativeTransformImageBrushRectangle = new Rectangle();
relativeTransformImageBrushRectangle.Width = 175;
relativeTransformImageBrushRectangle.Height = 90;
relativeTransformImageBrushRectangle.Stroke = Brushes.Black;
relativeTransformImageBrushRectangle.Fill = relativeTransformImageBrush;

'
' Create an ImageBrush with a relative transform and
' use it to paint a rectangle.
'
Dim relativeTransformImageBrush As New ImageBrush()
relativeTransformImageBrush.ImageSource = New BitmapImage(New Uri("sampleImages\pinkcherries.jpg", UriKind.Relative))

' Create a 45 rotate transform about the brush's center
' and apply it to the brush's RelativeTransform property.
Dim aRotateTransform As New RotateTransform()
aRotateTransform.CenterX = 0.5
aRotateTransform.CenterY = 0.5
aRotateTransform.Angle = 45
relativeTransformImageBrush.RelativeTransform = aRotateTransform

' Use the brush to paint a rectangle.
Dim relativeTransformImageBrushRectangle As New Rectangle()
relativeTransformImageBrushRectangle.Width = 175
relativeTransformImageBrushRectangle.Height = 90
relativeTransformImageBrushRectangle.Stroke = Brushes.Black
relativeTransformImageBrushRectangle.Fill = relativeTransformImageBrush

<Rectangle Width="175" Height="90" Stroke="Black">
  <Rectangle.Fill>
    <ImageBrush ImageSource="sampleImages\pinkcherries.jpg">
      <ImageBrush.RelativeTransform>
        <RotateTransform CenterX="0.5" CenterY="0.5" Angle="45" />
      </ImageBrush.RelativeTransform>
    </ImageBrush>
  </Rectangle.Fill>
</Rectangle>

下一示例也将 RotateTransform 应用于 ImageBrush;但使用 Transform 属性而不是 RelativeTransform 属性。 若要将画笔围绕其中心旋转,RotateTransform 对象的 CenterXCenterY 必须设置为绝对坐标。 由于画笔要绘制的矩形为 175 x 90 像素,因此它的中心点为 (87.5, 45)。

//
// Create an ImageBrush with a transform and
// use it to paint a rectangle.
//
ImageBrush transformImageBrush = new ImageBrush();
transformImageBrush.ImageSource =
    new BitmapImage(new Uri(@"sampleImages\pinkcherries.jpg", UriKind.Relative));

// Create a 45 rotate transform about the brush's center
// and apply it to the brush's Transform property.
RotateTransform anotherRotateTransform = new RotateTransform();
anotherRotateTransform.CenterX = 87.5;
anotherRotateTransform.CenterY = 45;
anotherRotateTransform.Angle = 45;
transformImageBrush.Transform = anotherRotateTransform;

// Use the brush to paint a rectangle.
Rectangle transformImageBrushRectangle = new Rectangle();
transformImageBrushRectangle.Width = 175;
transformImageBrushRectangle.Height = 90;
transformImageBrushRectangle.Stroke = Brushes.Black;
transformImageBrushRectangle.Fill = transformImageBrush;

'
' Create an ImageBrush with a transform and
' use it to paint a rectangle.
'
Dim transformImageBrush As New ImageBrush()
transformImageBrush.ImageSource = New BitmapImage(New Uri("sampleImages\pinkcherries.jpg", UriKind.Relative))

' Create a 45 rotate transform about the brush's center
' and apply it to the brush's Transform property.
Dim anotherRotateTransform As New RotateTransform()
anotherRotateTransform.CenterX = 87.5
anotherRotateTransform.CenterY = 45
anotherRotateTransform.Angle = 45
transformImageBrush.Transform = anotherRotateTransform

' Use the brush to paint a rectangle.
Dim transformImageBrushRectangle As New Rectangle()
transformImageBrushRectangle.Width = 175
transformImageBrushRectangle.Height = 90
transformImageBrushRectangle.Stroke = Brushes.Black
transformImageBrushRectangle.Fill = transformImageBrush

<Rectangle Width="175" Height="90" Stroke="Black">
  <Rectangle.Fill>
    <ImageBrush ImageSource="sampleImages\pinkcherries.jpg">
      <ImageBrush.Transform>
        <RotateTransform CenterX="87.5" CenterY="45" Angle="45" />
      </ImageBrush.Transform>
    </ImageBrush>
  </Rectangle.Fill>
</Rectangle>

下图显示没有转换的画笔、将转换应用到 RelativeTransform 属性的画笔以及将转换应用到 Transform 属性的画笔。

Brush RelativeTransform and Transform settings

此示例摘自一个更大的示例。 有关完整示例,请参阅 画笔示例。 有关画笔的详细信息,请参阅 WPF 画笔概述

另请参阅