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

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

В этом разделе содержатся следующие подразделы.

  • Рисование и фигуры
  • Объекты StreamGeometry
  • Объекты DrawingVisual
  • Изображения
  • Связанные разделы

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

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 выводит другие объекты Drawing. Используйте группирование объектов Drawing для объединения объектов Drawing в один составной объект Drawing.

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

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

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

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

Объекты StreamGeometry

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

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

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

Объекты DrawingVisual

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

Изображения

Обработка изображений в WPF значительно улучшилась по сравнению с возможностями обработки изображений в предыдущих версиях Windows. Возможности обработки изображений, такие как отображение точечных рисунков или использование изображения на общем элементе управления в основном обрабатывались прикладными программными интерфейсами Microsoft Windows Graphics Device Interface (GDI) или Microsoft Windows GDI+. Эти интерфейсы 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.

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

См. также

Основные понятия

Улучшение производительности приложений WPF

Планирование производительности приложения

Оптимизация производительности. Использование преимуществ аппаратного ускорения

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

Оптимизация производительности: поведение объекта

Оптимизация производительности: ресурсы приложения

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

Оптимизация производительности: привязка данных

Оптимизация производительности. Дополнительные рекомендации

Советы и рекомендации по анимации