Información general sobre la transformación de pinceles

La clase Brush proporciona dos propiedades de transformación: Transform y RelativeTransform. Las propiedades permiten girar, escalar, sesgar y trasladar el contenido de un pincel. En este tema se describen las diferencias entre estas dos propiedades y proporciona ejemplos de su uso.

Prerrequisitos

Para entender este tema, debe entender las características del pincel que se va a transformar. Para LinearGradientBrush y RadialGradientBrush, consulte Información general sobre el dibujo con colores sólidos y degradados. Para ImageBrush, DrawingBrush o VisualBrush, consulte Pintar con imágenes, dibujos y objetos visuales. También debe estar familiarizado con las transformaciones 2D descritas en Información general sobre transformaciones.

Diferencias entre las propiedades Transform y RelativeTransform

Al aplicar una transformación a la propiedad Transform de un pincel, debe conocer el tamaño del área pintada si desea transformar el contenido del pincel sobre su centro. Supongamos que el área pintada tiene 200 píxeles independientes del dispositivo de ancho y 150 de alto. Si ha usado RotateTransform para girar la salida del pincel 45 grados sobre su centro, daría a RotateTransform un valor de CenterX de 100 y un valor de CenterY de 75.

Al aplicar una transformación a una propiedad RelativeTransform de un pincel, esa transformación se aplica al pincel antes de que la salida se haya asignado al área pintada. En la lista siguiente se describe el orden en el que se procesan y transforman los contenidos de un pincel.

  1. Procese el contenido del pincel. Para GradientBrush, esto significa determinar el área de degradado. Para TileBrush, el objeto Viewbox se asigna a Viewport. Esto se convierte en la salida del pincel.

  2. Proyecte la salida del pincel en el rectángulo de transformación de 1 x 1.

  3. Aplique el objeto RelativeTransform del pincel, si lo tiene.

  4. Proyecte la salida transformada en el área que se va a pintar.

  5. Aplique el objeto Transform del pincel, si lo tiene.

Dado que el objeto RelativeTransform se aplica mientras la salida del pincel se asigna a un rectángulo de 1 x 1, el centro de transformación y los valores de desplazamiento parecen ser relativos. Por ejemplo, si ha usado RotateTransform para girar la salida del pincel 45 grados sobre su centro, daría a RotateTransform un valor de CenterX de 0.5 y un valor de CenterY de 0.5.

En la ilustración siguiente se muestra la salida de varios pinceles que se han girado 45 grados mediante las propiedades RelativeTransform y Transform.

Propiedades RelativeTransform y Transform

Utilizar RelativeTransform con un objeto TileBrush

Como los pinceles de diseño en mosaico son más complejos que otros pinceles, la aplicación de una propiedad RelativeTransform a uno de ellos podría producir resultados inesperados. Por ejemplo, veamos la imagen siguiente.

Imagen de origen

En el ejemplo siguiente se usa un elemento ImageBrush para pintar un área rectangular con la imagen anterior. Aplica un elemento RotateTransform a la ImageBrush propiedad RelativeTransform del objeto, y establece su propiedad Stretch en UniformToFill, lo que debería conservar la relación de aspecto de la imagen cuando se ajusta para rellenar por completo el rectángulo.

<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>

Este ejemplo produce el siguiente resultado:

Salida transformada

Observe que la imagen está distorsionadas, incluso si el elemento Stretch del pincel se estableció en UniformToFill. Eso se debe a que la transformación relativa se aplica después de que el elemento Viewbox del pincel se haya asignado a su Viewport. La lista siguiente describe cada paso del proceso:

  1. Proyecte el contenido del pincel (Viewbox) en su icono base (Viewport) mediante la configuración Stretch del pincel.

    Estirar Viewbox para que se ajuste a Viewport

  2. Proyecte el icono base del rectángulo de transformación de 1 x 1.

    Asignar Viewport al rectángulo de transformación

  3. Aplique el objeto RotateTransform.

    Aplicar la transformación relativa

  4. Proyecte el icono base transformado en el área que se va a pintar.

    Proyectar el pincel transformado en el área de salida

Ejemplo: Girar un objeto ImageBrush 45 grados

En el siguiente ejemplo se aplica un elemento RotateTransform a la propiedad RelativeTransform de un elemento ImageBrush. Las propiedades CenterX y CenterY del objeto RotateTransform se establecen en 0,5, las coordenadas relativas del punto central del contenido. Como resultado, el contenido del pincel se gira sobre su centro.

//
// 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>

En el ejemplo siguiente también se aplica un elemento RotateTransform a ImageBrush, pero se usa la propiedad Transform en lugar de la propiedad RelativeTransform. Para girar el pincel sobre su centro, las propiedades CenterX y CenterY del objeto RotateTransform deben establecerse en coordenadas absolutas. Como el rectángulo pintado por el pincel es 175 por 90 píxeles, su punto central es (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>

En la ilustración siguiente se muestra el pincel sin una transformación, con la transformación aplicada a la propiedad RelativeTransform, y con la transformación aplicada a la propiedad Transform.

Valores de RelativeTransform y Transform de Brush

Este ejemplo forma parte de un ejemplo mayor. Para ver el ejemplo completo, consulte el ejemplo de pinceles. Para obtener más información, consulte Información general sobre pinceles de WPF.

Vea también