Otimizando desempenho: elementos gráficos e geração de imagens 2D

O WPF fornece uma ampla gama de gráficos 2D e funcionalidade de imagem que podem ser otimizadas para os requisitos do seu aplicativo. Este tópico fornece informações sobre otimização de desempenho nessas áreas.

Desenho e formas

WPF fornece ambos e DrawingShape objetos para representar o conteúdo do desenho gráfico. No entanto, Drawing os objetos são construções mais simples do que Shape os objetos e fornecem melhores características de desempenho.

A Shape permite desenhar uma forma gráfica para a tela. Como eles são derivados da classe, Shape os FrameworkElement objetos podem ser usados dentro de painéis e da maioria dos controles.

O WPF oferece várias camadas de acesso a gráficos e serviços de renderização. Na camada superior, os objetos são fáceis de usar e fornecem muitos recursos úteis, Shape como layout e manipulação de eventos. O WPF fornece vários objetos de forma prontos para uso. Todos os objetos de forma herdam da Shape classe. Os objetos de forma disponíveis incluem Ellipse, , , LinePolygonPath, Polylinee .Rectangle

Drawing objetos, por outro lado, não derivam da FrameworkElement classe e fornecem uma implementação mais leve para renderizar formas, imagens e texto.

Existem quatro tipos de Drawing objetos:

O GeometryDrawing objeto é usado para renderizar o conteúdo da geometria. A Geometry classe e as classes concretas que derivam dela, como CombinedGeometry, e , EllipseGeometryfornecem um meio para renderizar gráficos 2D e fornecer suporte a testes de acerto e PathGeometryrecorte. Objetos geométricos podem ser usados para definir a região de um controle, por exemplo, ou para definir a região de corte para aplicar a uma imagem. Objetos geométricos podem ser regiões simples, como retângulos e círculos ou regiões de composição criadas de dois ou mais objetos geométricos. Regiões geométricas mais complexas podem ser criadas combinando PathSegmentobjetos derivados, como ArcSegment, BezierSegmente QuadraticBezierSegment.

Na superfície, a classe e a GeometryShape classe são semelhantes. Ambos são usados na renderização de gráficos 2D e ambos têm classes concretas semelhantes que derivam deles, por exemplo, EllipseGeometry e Ellipse. No entanto, existem diferenças importantes entre esses dois conjuntos de classes. Por um lado, a classe carece de algumas das funcionalidades da classe, como a Geometry capacidade de Shape desenhar a si mesma. Para desenhar um objeto geométrico, outra classe, como DrawingContext, Drawing ou Path (vale a pena observar que um Path é um Shape) deve ser usada para executar a operação de desenho. As propriedades de renderização, como preenchimento, traçado e espessura do traçado, estão na classe que desenha o objeto de geometria, enquanto um objeto de forma contém essas propriedades. Uma maneira de pensar nessa diferença é que um objeto de geometria define uma região, por exemplo, um círculo, enquanto um objeto de forma define uma região, define como essa região é preenchida e delineada e participa do sistema de layout.

Como Shape os objetos derivam da classe, usá-los FrameworkElement pode adicionar significativamente mais consumo de memória em seu aplicativo. Se você realmente não precisa dos FrameworkElement recursos para seu conteúdo gráfico, considere usar os objetos mais leves Drawing .

Para obter mais informações sobre objetos, consulte Visão geral sobre Drawing objetos de desenho.

Classe StreamGeometry

O StreamGeometry objeto é uma alternativa leve para PathGeometry criar formas geométricas. Use um StreamGeometry quando você precisar descrever uma geometria complexa. StreamGeometry é otimizado para lidar com muitos objetos e tem um desempenho melhor quando comparado ao uso de muitos PathGeometry objetos individuais PathGeometry .

O exemplo a seguir usa a sintaxe de atributo para criar uma triangular StreamGeometry em XAML.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <StackPanel>
  
    <Path Data="F0 M10,100 L100,100 100,50Z" 
      StrokeThickness="1" Stroke="Black"/>

  </StackPanel>
</Page>

Para obter mais informações sobre StreamGeometry objetos, consulte Criar uma forma usando um StreamGeometry.

Objetos DrawingVisual

O DrawingVisual objeto é uma classe de desenho leve usada para renderizar formas, imagens ou texto. Essa classe é considerada leve porque não fornece layout ou manipulação de eventos, o que melhora o desempenho. Por esse motivo, desenhos são ideais para telas de fundo e clip-art. Para obter mais informações, consulte Usando objetos DrawingVisual.

Imagens

A geração de imagens do WPF fornece uma melhoria significativa em relação aos recursos de geração de imagens em versões anteriores do Windows. Os recursos de geração de imagens, como a exibição de um bitmap ou o uso de uma imagem em um controle comum, eram manipulados principalmente pela Microsoft Windows Graphics Device Interface (GDI) ou pela API (Application Programming Interface) do Microsoft Windows GDI+. Essas APIs forneciam funcionalidade de imagem de linha de base, mas não tinham recursos como suporte para extensibilidade de codec e suporte a imagens de alta fidelidade. As APIs do WPF Imaging foram reprojetadas para superar as deficiências do GDI e do GDI+ e fornecer um novo conjunto de APIs para exibir e usar imagens em seus aplicativos.

Ao usar imagens, considere as seguintes recomendações para obter um melhor desempenho:

  • Se seu aplicativo requer que você exiba imagens em miniatura, considere a criação de uma versão de tamanho reduzido da imagem. Por padrão, o WPF carrega sua imagem e a decodifica para seu tamanho total. Se você quiser apenas uma versão em miniatura da imagem, o WPF desnecessário decodifica a imagem para seu tamanho completo e, em seguida, a reduz para um tamanho de miniatura. Para evitar essa sobrecarga desnecessária, você pode solicitar que o WPF decodifice a imagem para um tamanho de miniatura ou solicitar que o WPF carregue uma imagem de tamanho miniatura.

  • Sempre decodifique a imagem para o tamanho desejado e não para o tamanho padrão. Como mencionado acima, solicite ao WPF para decodificar sua imagem para um tamanho desejado e não para o tamanho completo padrão. Você reduzirá não apenas seu conjunto de trabalho do aplicativo, mas também a velocidade de execução.

  • Se possível, combine as imagens em uma única imagem, como um filme composto de várias imagens.

  • Para obter mais informações, consulte Visão geral de geração de imagens.

BitmapScalingMode

Ao animar a escala de qualquer bitmap, o algoritmo padrão de reamostragem de imagem de alta qualidade às vezes pode consumir recursos suficientes do sistema para causar degradação da taxa de quadros, efetivamente causando interrupções nas animações. Ao definir a BitmapScalingModeRenderOptions propriedade do objeto como LowQuality, você pode criar uma animação mais suave ao dimensionar um bitmap. LowQuality O modo diz ao mecanismo de renderização WPF para alternar de um algoritmo otimizado para qualidade para um algoritmo otimizado para velocidade ao processar imagens.

O exemplo a seguir mostra como definir o BitmapScalingMode para um objeto image.

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

Por padrão, o WPF não armazena em cache o conteúdo renderizado de TileBrush objetos, como DrawingBrush e VisualBrush. Em cenários estáticos onde o conteúdo ou o uso do na cena não estão mudando, isso faz sentido, já que conserva a memória de TileBrush vídeo. Não faz tanto sentido quando um com conteúdo estático é usado de forma não estática — por exemplo, quando um estático DrawingBrush ou VisualBrush é mapeado para a superfície de um TileBrush objeto 3D em rotação. O comportamento padrão do WPF é renderizar novamente todo o DrawingBrush conteúdo do ou VisualBrush para cada quadro, mesmo que o conteúdo seja imutável.

Definindo a propriedade do objeto como Cache, você pode aumentar o desempenho usando versões em cache dos objetos de pincel lado a CachingHintRenderOptions lado.

Os CacheInvalidationThresholdMinimum valores de propriedade e são valores de CacheInvalidationThresholdMaximum tamanho relativo que determinam quando o objeto deve ser regenerado TileBrush devido a alterações na escala. Por exemplo, definindo a CacheInvalidationThresholdMaximum propriedade como 2.0, o cache do TileBrush somente precisa ser regenerado quando seu tamanho excede o dobro do tamanho do cache atual.

O exemplo a seguir mostra como usar a opção de dica de cache para um DrawingBrusharquivo .

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

Confira também