Общие сведения о преобразованиях кистей

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

Необходимые компоненты

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

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

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

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

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

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

  3. Примените RelativeTransform кисти, при наличии.

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

  5. Примените Transform кисти, при наличии.

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

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

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. Спроектируйте содержимое кисти (Viewbox) на ее базовый фрагмент (Viewport) с помощью параметра кистиStretch.

    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 применяется к свойству 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. Чтобы повернуть кисть вокруг центра, для объекта RotateTransformCenterX и 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.

Brush RelativeTransform and Transform settings

Данный пример является частью большого примера. Полный пример см. в разделе Пример использования кистей. Более подробные сведения о кистях см. в разделе Общие сведения о кистях WPF.

См. также