Оптимизация производительности: двумерная графика и обработка изображений

WPF предоставляет широкий спектр функциональных возможностей двумерной графики и изображений, которые можно оптимизировать для требований приложения. Этот раздел содержит сведения об оптимизации производительности в этих областях.

Рисование и фигуры

WPF предоставляет объекты Drawing и Shape для представления графического содержимого документа. Однако объекты Drawing представляют собой более простые конструкции, чем объекты Shape, и обеспечивают более высокую производительность.

Shape позволяет рисовать графические фигуры на экране. Учитывая, что объекты Shape являются производными от класса FrameworkElement, их можно использовать в панелях и большинстве элементов управления.

WPF предоставляет несколько уровней доступа к службам для работы с графикой и службам рендеринга. На верхнем уровне объекты Shape просты в использовании и предоставляют множество полезных функций, таких как макет и обработка событий. WPF предоставляет ряд готовых к использованию объектов фигуры. Все объекты фигуры наследуют от класса Shape. Доступные объекты фигур: Ellipse, Line, Path, Polygon, Polyline и Rectangle.

С другой стороны, объекты Drawing не являются производными от класса FrameworkElement и предоставляют упрощенную реализацию отрисовки фигур, изображений и текста.

Существует четыре типа объектов Drawing.

  • GeometryDrawing — рисует фигуру.

  • ImageDrawing — рисует изображение.

  • GlyphRunDrawing — рисует текст.

  • DrawingGroup — рисует другие рисунки. Для объединения рисунков в один составной рисунок используйте группирование рисунков.

Объект GeometryDrawing используется для отрисовки содержимого геометрии. Класс Geometry и конкретные классы, которые являются производными от него, например, CombinedGeometry, EllipseGeometry и PathGeometry, предоставляют средство отрисовки двумерной графики, а также поддержку тестирования и обрезки. Геометрические объекты можно использовать, например, для определения области элемента управления или для определения области усечения, применяемой к изображению. Геометрические объекты могут быть простыми, такими как прямоугольники и круги, или сложными, созданными из двух или более геометрических объектов. Более сложные геометрические области можно создать путем объединения объектов, производных от PathSegment, таких как ArcSegment, BezierSegment и QuadraticBezierSegment.

Классы Geometry и Shape на поверхности похожи друг на друга. Оба эти класса используются для отрисовки двумерной графики, и оба содержат похожие конкретные классы, которые являются производными от них, например, EllipseGeometry и Ellipse. Однако существуют важные различия между этими двумя наборами классов. В одном случае классу Geometry не хватает функциональных возможностей класса Shape, например, возможности отрисовывать самого себя. Чтобы нарисовать геометрический объект, для выполнения операции рисования должен использоваться другой класс, например DrawingContext, Drawing или Path (стоит отметить, что Path является Shape). Свойства рендеринга, такие как заливка (fill), штрих (stroke) и толщина штриха (stroke thickness), находятся в классе, который рисует этот геометрический объект, в то время как объект фигуры содержит эти свойства. Чтобы понять это различие, представьте, что геометрический объект определяет область, например круг, а объект фигуры определяет область, определяет, как эта область заполняется и обводится, а также участвует в системе макета.

Поскольку объекты Shape являются производными от класса FrameworkElement, их использование может значительно увеличить потребление памяти в приложении. Если вам на самом деле не требуются компоненты FrameworkElement графического содержимого, можно использовать более простые и легковесные объекты Drawing.

Дополнительные сведения об объектах Drawing см. в разделе Общие сведения о графических объектах.

Объекты StreamGeometry

Объект StreamGeometry является упрощенной альтернативой PathGeometry для создания геометрических фигур. Используйте StreamGeometry, если требуется описать сложную геометрию. StreamGeometry оптимизирован для обработки нескольких объектов PathGeometry и отличается более высокой производительностью в сравнении с использованием множества отдельных объектов PathGeometry.

В следующем примере используется синтаксис атрибутов для создания треугольного объекта StreamGeometry в 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>

Дополнительные сведения об объектах StreamGeometry см. в разделе Создание фигуры с помощью StreamGeometry.

объекты DrawingVisual

Объект DrawingVisual — это упрощенный класс рисования, который используется для отрисовки фигур, изображений и текста. Этот класс считается упрощенным, так как не предоставляет средств для работы с разметкой и обработку событий, что повышает его производительность. Поэтому этот класс идеально подходит для фоновых рисунков или клипов. Дополнительные сведения см. в разделе Использование объектов DrawingVisual.

изображения;

Обработка изображений в WPF значительно улучшилась по сравнению с возможностями обработки изображений в предыдущих версиях Windows. Возможности обработки изображений, например вывод растрового изображения или использование изображения в общем элементе управления, в основном управлялись интерфейсом графических устройств (GDI) Microsoft Windows или Microsoft Windows GDI и программным интерфейсом (API). Эти API обеспечивали базовые функции обработки изображений, но в них отсутствовали такие возможности, как поддержка расширяемости кодеков и изображений высокого качества. API обработки изображений WPF был переработан для преодоления недостатков GDI и GDI+ и теперь предоставляет новый набор API для отображения и использования изображений в приложениях.

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

  • Если в приложении требуется отображение эскизов, рассмотрите возможность создания версий изображений уменьшенного размера. По умолчанию WPF загружает изображение и преобразует его до полного размера. Если требуется только эскиз изображения, WPF напрасно преобразует изображение до полного размера, а затем масштабирует его до размера эскиза. Чтобы избежать этой лишней нагрузки, можно либо запросить в WPF преобразование изображения в размер эскиза, либо настроить WPF для загрузки изображения размера эскиза.

  • Всегда преобразуйте изображение в нужный размер, а не размер по умолчанию. Как упоминалось выше, запросите в WPF преобразование изображения в нужный размер, а не в полный размер по умолчанию. Вы уменьшите не только рабочий набор приложения, но также и время ожидания выполнения.

  • Если это возможно, объединяйте изображения в одно изображение, например диафильм, состоящий из нескольких изображений.

  • Более подробную информацию см. в разделе Общие сведения об обработке изображений.

BitmapScalingMode

При анимации масштабирования любого растрового изображения алгоритм повторной дискретизации изображения высокого качества по умолчанию иногда может использовать столько системных ресурсов, чтобы привести к снижению частоты кадров анимации и задержкам. Настроив для свойства BitmapScalingMode объекта RenderOptions значение LowQuality, моно создать более плавную анимацию при масштабировании растрового изображения. Режим LowQuality указывает механизму рендеринга WPF при обработке изображений переключиться с алгоритма, оптимизированного по качеству, на алгоритм, оптимизированный по скорости.

В следующем примере показано, как задать свойство BitmapScalingMode для объекта изображения.

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

По умолчанию в WPF не кэшируется отрисованное содержимое объектов TileBrush, например, DrawingBrush и VisualBrush. В статических сценариях, где не изменяется ни содержимое, ни использование TileBrush, это имеет смысл, так как экономит видеопамять. Это не так удобно, если TileBrush со статическим содержимым используется в нестатическом режиме; например, если статический DrawingBrush или VisualBrush сопоставляется с поверхностью вращающегося трехмерного объекта. Поведение WPF по умолчанию предполагает отрисовку всего содержимого DrawingBrush и VisualBrush для каждого кадра, даже если содержимое не изменяется.

Настроив свойство CachingHint объекта RenderOptions со значением Cache, можно повысить производительность, используя кэшированные версии объектов мозаичной кисти.

Значения свойства CacheInvalidationThresholdMinimum и CacheInvalidationThresholdMaximum являются значениями относительного размера, которые определяют время повторного создания объекта TileBrush после изменения масштаба. Например, если для свойства CacheInvalidationThresholdMaximum задано значение 2.0, кэш для TileBrush необходимо повторно создать только в том случае, если его размер превышает размер текущего кэша вдвое.

В следующем примере показано, как использовать параметр подсказки кэширования для DrawingBrush.

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)

См. также