Optimizar el rendimiento: Imágenes y gráficos 2D

WPF proporciona una gama amplia de gráficos 2D y funcionalidad de creación de imágenes que se pueden optimizar para los requisitos de la aplicación. En este tema se proporciona información sobre la optimización del rendimiento en esas áreas.

Este tema contiene las secciones siguientes.

  • Dibujos y formas
  • Objetos StreamGeometry
  • Objetos DrawingVisual
  • Imágenes
  • Temas relacionados

Dibujos y formas

WPF proporciona objetos Drawing y Shape para representar el contenido de los dibujos gráficos. Sin embargo, los objetos Drawing son estructuras más sencillas que los objetos Shape y proporcionan mejores características de rendimiento.

Un objeto Shape permite dibujar una forma gráfica en la pantalla. Dado que se derivan de la clase FrameworkElement, los objetos Shape se pueden utilizar dentro de los paneles y de la mayoría de los controles.

WPF ofrece varias capas de acceso a los gráficos y a los servicios de representación. En la capa superior, los objetos Shape son fáciles de utilizar y proporcionan numerosas características útiles, tales como la administración del diseño y el control de eventos. WPF proporciona varios objetos de forma listos para usar. Todos los objetos de formas heredan de la clase Shape. Los objetos de formas disponibles incluyen Ellipse, Line, Path, Polygon, Polyline y Rectangle.

Por otro lado, los objetos Drawing no se derivan de la clase FrameworkElement y proporcionan una implementación más ligera para representar formas, imágenes y texto.

Hay cuatro tipos de objetos Drawing:

El objeto GeometryDrawing se utiliza para representar contenido de geometría. La clase Geometry y las clases concretas que se derivan de ella, tales como CombinedGeometry, EllipseGeometry y PathGeometry, proporcionan un medio para representar gráficos 2D, además de compatibilidad con las pruebas de posicionamiento y el recorte. Los objetos de geometría se pueden utilizar para definir la región de un control, por ejemplo, o definir la región de recorte que se aplicará a una imagen. Los objetos de geometría pueden ser regiones simples, tales como rectángulos y círculos, o bien regiones compuestas creadas a partir de dos o más objetos de geometría. Las regiones de geometría más complejas se pueden crear combinando objetos derivados de PathSegment, como ArcSegment, BezierSegment y QuadraticBezierSegment.

Aparentemente, la clase Geometry y la clase Shape son bastante similares. Ambas se utilizan para representar gráficos 2D y tienen clases concretas similares que se derivan de ellas, por ejemplo, EllipseGeometry y Ellipse. Sin embargo, existen diferencias importantes entre estos dos conjuntos de clases. En primer lugar, la clase Geometry carece de parte de la funcionalidad de la clase Shape, como la capacidad de dibujarse a sí misma. Para dibujar un objeto de geometría, deberá utilizarse otra clase, del tipo de DrawingContext, Drawing o Path (cabe destacar que Path es una forma) para realizar la operación de dibujo. Las propiedades de representación, tales como el relleno, el trazo y el grosor del trazo pertenecen a la clase que dibuja el objeto de geometría, mientras que un objeto de forma contiene estas propiedades. Podemos pensar en esta diferencia de la siguiente manera: un objeto de geometría define una región, un círculo por ejemplo, mientras que un objeto de forma define una región, define cómo se rellena y perfila esa región, y participa en el sistema de diseño.

Puesto que los objetos Shape se derivan de la clase FrameworkElement, utilizarlos puede aumentar significativamente el consumo de memoria de la aplicación. Si realmente no necesita las características de FrameworkElement para el contenido gráfico, es conveniente utilizar los objetos Drawing, más ligeros.

Para obtener más información sobre los objetos Drawing, consulte Información general sobre objetos Drawing.

Objetos StreamGeometry

El objeto StreamGeometry constituye una alternativa ligera a PathGeometry para crear formas geométricas. Utilice un objeto StreamGeometry cuando necesite describir una geometría compleja. StreamGeometry está optimizada para administrar muchos objetos PathGeometry y registra un rendimiento mejor que cuando se utilizan varios objetos PathGeometry individuales.

En el ejemplo siguiente se utiliza la sintaxis de atributo para crear una StreamGeometry triangular en XAML.

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
  <StackPanel>

    <Path Data="F0 M10,100 L100,100 100,50Z" 
      StrokeThickness="1" Stroke="Black"/>

  </StackPanel>
</Page>

Para obtener más información sobre los objetos StreamGeometry, consulte Cómo: Crear una forma utilizando StreamGeometry.

Objetos DrawingVisual

El objeto DrawingVisual es una clase de dibujo ligera que se utiliza para representar formas, imágenes o texto. Esta clase se considera ligera porque no proporciona administración del diseño ni control de eventos, lo que mejora su rendimiento. Por esta razón, los dibujos son idóneos para fondos e imágenes prediseñadas. Para obtener más información, consulte Usar objetos DrawingVisual.

Imágenes

La creación de imágenes de WPF proporciona una mejora significativa con respecto a las funciones de creación de imágenes de las versiones anteriores de Windows. Las funciones de creación de imágenes, tales como la presentación de mapas de bits o el uso de imágenes en controles comunes, se administraban principalmente por las interfaces de programación de aplicaciones (API) de la interfaz de dispositivo gráfico (GDI) o de la GDI+ de Microsoft Windows. Estas API proporcionaban la funcionalidad básica para la creación de imágenes, pero carecían de características tales como compatibilidad con la extensibilidad de códec y con imágenes de alta fidelidad. La API de creación de imágenes de WPF se ha rediseñado para superar las limitaciones de GDI y GDI+ y proporcionar un nuevo conjunto de API para mostrar y utilizar imágenes en las aplicaciones.

Al utilizar imágenes, tenga en cuenta las recomendaciones siguientes para obtener el mejor rendimiento:

  • Si su aplicación le exige que muestre imágenes en miniatura, puede ser conveniente crear una versión de dimensiones reducidas de la imagen. De manera predeterminada, WPF carga la imagen y la descodifica a su tamaño completo. Si sólo desea una versión en miniatura de la imagen, WPF descodifica innecesariamente la imagen a su tamaño completo y, a continuación, la reduce a la escala en miniatura. Para evitar este consumo de recursos innecesario, puede solicitar a WPF que descodifique la imagen a un tamaño en miniatura o bien solicitar a WPF que cargue una imagen en miniatura.

  • Siempre descodifique la imagen al tamaño deseado y no al tamaño predeterminado. Como hemos explicado anteriormente, solicite a WPF que descodifique la imagen al tamaño deseado y no al tamaño completo predeterminado. De este modo, no sólo mejorará el espacio de trabajo de la aplicación, sino también la velocidad de ejecución.

  • Si es posible, combine las imágenes en una imagen única, como una tira cinematográfica creada de varias imágenes.

  • Para obtener más información, consulte Información general sobre imágenes.

BitmapScalingMode

Al animar la escala de un mapa de bits, el algoritmo de remuestreo predeterminado de las imágenes de alta calidad, a veces, puede consumir tantos recursos del sistema que cause la degradación de la velocidad de los fotogramas, lo que provoca el parpadeo de las animaciones. Si establece el valor de la propiedad BitmapScalingMode del objeto RenderOptions en LowQuality, podrá crear una animación más suavizada al escalar un mapa de bits. El modo LowQuality indica al motor de representación de WPF que cambie de un algoritmo optimizado para la calidad a un algoritmo optimizado para la velocidad al procesar las imágenes.

En el siguiente ejemplo se muestra cómo establecer el valor de BitmapScalingMode para un objeto de imagen.

            ' Set the bitmap scaling mode for the image to render faster.
            RenderOptions.SetBitmapScalingMode(MyImage, BitmapScalingMode.LowQuality)
// Set the bitmap scaling mode for the image to render faster.
RenderOptions.SetBitmapScalingMode(MyImage, BitmapScalingMode.LowQuality);

CachingHint

De manera predeterminada, WPF no almacena en memoria caché el contenido representado de los objetos TileBrush, como DrawingBrush y VisualBrush. En escenarios estáticos donde no cambia el contenido ni el uso de TileBrush en la escena, esto tiene sentido dado que conserva la memoria de vídeo. No tiene tanto sentido cuando se usa un objeto TileBrush con contenido estático de forma no estática; por ejemplo, cuando se asigna un objeto DrawingBrush o VisualBrush estático a la superficie de un objeto 3D que gira. El comportamiento predeterminado de WPF es volver a representar el contenido completo de cada fotograma de DrawingBrush o VisualBrush, aunque no cambie el contenido.

Si se establece el valor de la propiedad CachingHint del objeto RenderOptions en Cache, podrá aumentar el rendimiento utilizando versiones almacenadas en memoria caché de los objetos de pincel en mosaico.

Los valores de las propiedades CacheInvalidationThresholdMaximum y CacheInvalidationThresholdMinimum son valores de tamaño relativo que determinan cuándo se debe regenerar el objeto TileBrush debido a cambios en la escala. Por ejemplo, si establece el valor de la propiedad CacheInvalidationThresholdMaximum en 2.0, la memoria caché del objeto TileBrush sólo necesita regenerarse cuando su tamaño supere el doble del tamaño de la caché actual.

En el ejemplo siguiente se muestra cómo utilizar la opción de sugerencia de almacenamiento en caché para DrawingBrush.

            Dim drawingBrush As New DrawingBrush()

            ' Set the caching hint option for the brush.
            RenderOptions.SetCachingHint(drawingBrush, CachingHint.Cache)

            ' Set the minimum and maximum relative sizes for regenerating the tiled brush.
            ' The tiled brush will be regenerated and re-cached when its size is
            ' 0.5x or 2x of the current cached size.
            RenderOptions.SetCacheInvalidationThresholdMinimum(drawingBrush, 0.5)
            RenderOptions.SetCacheInvalidationThresholdMaximum(drawingBrush, 2.0)
DrawingBrush drawingBrush = new DrawingBrush();

// Set the caching hint option for the brush.
RenderOptions.SetCachingHint(drawingBrush, CachingHint.Cache);

// Set the minimum and maximum relative sizes for regenerating the tiled brush.
// The tiled brush will be regenerated and re-cached when its size is
// 0.5x or 2x of the current cached size.
RenderOptions.SetCacheInvalidationThresholdMinimum(drawingBrush, 0.5);
RenderOptions.SetCacheInvalidationThresholdMaximum(drawingBrush, 2.0);

Vea también

Conceptos

Optimizar WPF: Rendimiento de aplicaciones

Planear para mejorar el rendimiento de aplicaciones

Optimizar el rendimiento: Aprovechar el hardware

Optimizar el rendimiento: Presentación y diseño

Optimizar el rendimiento: Comportamiento de objetos

Optimizar el rendimiento: Recursos de aplicación

Optimizar el rendimiento: Texto

Optimizar el rendimiento: Enlace de datos

Optimizar el rendimiento: Otras recomendaciones

Sugerencias y trucos para animaciones