Поделиться через


Обзор преобразования кисти

Класс Brush предоставляет два свойства преобразования: Transform и RelativeTransform. Свойства позволяют поворачивать, масштабировать, искажать и перемещать содержимое кисти. В этом разделе описываются различия между этими двумя свойствами и приведены примеры их использования.

Предпосылки

Чтобы понять эту тему, необходимо понять особенности преобразуемой кисти. Дополнительные сведения о LinearGradientBrush и RadialGradientBrush см. в разделе "Обзор рисования со сплошными цветами и градиентами". Для ImageBrush, DrawingBrush, или VisualBrush см. раздел Рисование с изображениями, рисунками и визуальными элементами. Вы также должны ознакомиться с 2D-преобразованиями, описанными в обзоре преобразований.

Различия между свойствами Transform и RelativeTransform

При применении преобразования к свойству кисти Transform, необходимо знать размер окрашенной области, если хотите преобразовать содержимое кисти относительно её центра. Предположим, что окрашенная область составляет 200 пикселей, независимых от устройства, в ширину и 150 в высоту. Если вы использовали RotateTransform для поворота результата работы кисти на 45 градусов вокруг его центра, вы бы задали RotateTransform значение CenterX 100 и CenterY 75.

При нанесении преобразования на свойство кисти, это преобразование применяется к ней перед тем, как её выходные данные сопоставляются с окрашенной областью. В следующем списке описывается порядок обработки и преобразования содержимого кисти.

  1. Обработайте содержимое кисти. Для параметра GradientBrush, это означает определение градиентной области. Для параметра TileBrushViewbox привязывается к Viewport. Это становится результатом работы кисти.

  2. Проецируйте вывод кисти на прямоугольник преобразования размером 1 x 1.

  3. Примените кисть RelativeTransform, если она имеет один.

  4. Проецировать преобразованные выходные данные на область для рисования.

  5. Примените кисть Transform, если она имеет один.

Поскольку RelativeTransform применяется, когда выходные данные кисти сопоставляются с прямоугольником 1 x 1, значения центра преобразования и смещения выглядят относительными. Например, если вы использовали RotateTransform для поворота эффекта кисти на 45 градусов вокруг ее центра, вы бы дали RotateTransformCenterX 0.5 и CenterY 0.5.

На следующем рисунке показан результат работы нескольких кистей, которые были повернуты на 45 градусов с помощью свойств RelativeTransform и Transform.

Свойства RelativeTransform и Transform

Использование RelativeTransform с кистью TileBrush

Поскольку кисти для плитки более сложны, чем другие кисти, применение RelativeTransform к ним может привести к неожиданным результатам. Например, рассмотрите следующее изображение.

Исходный образ

В следующем примере используется 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>

В примере получается следующий вывод.

Преобразованный вывод

Заметьте, что изображение искажается, несмотря на то что кисть была настроена на Stretch. Это связано с тем, что относительное преобразование применяется после того, как Viewbox кисти сопоставляется с Viewport. В следующем списке описывается каждый этап процесса:

  1. Проецируйте содержимое кисти (Viewbox) на базовую плитку (Viewport), используя параметр кисти Stretch.

    Растяните Viewbox, чтобы он соответствовал Viewport

  2. Проецируйте плитку основы на прямоугольник преобразования размером 1 x 1.

    Сопоставление окна представления с прямоугольником преобразования

  3. Примените RotateTransform.

    Применение относительного преобразования

  4. Проецировать преобразованную базовую плитку на область для окрашивания.

    Проецируйте преобразованную кисть на область вывода

Пример: Поворот ImageBrush на 45 градусов

В следующем примере RotateTransform применяется к свойству RelativeTransform объекта ImageBrush. Значения свойств RotateTransform и CenterX объекта CenterY установлены на 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 объекта должны быть установлены абсолютные координаты CenterX и CenterY. Так как прямоугольник, окрашенный кистью, составляет 175 на 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 .

настройки кисти RelativeTransform и Transform

Этот пример является частью более крупного примера. Полный образец см. в Brushes Sample. Для получения дополнительной информации о кистях см. Обзор кистей WPF.

См. также