Я нашел несколько шаблонов для оптимизации обработки битмапов в WPF. Однако я не понимаю, когда использовать каждый образец. Поскольку я думаю, что это распространенная проблема, я подытожил то, что я понимаю, и что я думаю, и прошу вас о помощи. Если вы можете добавить паттерны, объяснить как они отличаются, объяснить, если они используют CPU или GPU, и научить когда использовать каждый и , как объединить их, это была бы огромная помощь !Шаблоны оптимизации производительности Bitmap
Контекст - образы «Сетка» Сценарий:
Мое приложение должно отображать множество растровых изображений. Изображения отображаются на экране в сетчатой организации строк и столбцов (не обязательно для классов Grid или UniformGrid, думайте о просмотре альбома Window Media Player). Изображения могут перемещаться между различными ячейками сетки. Некоторые изображения в произвольных ячейках могут быть заменены другими. Изображения должны быть интерактивными, содержать контекстное меню, выбирать, перетаскивать и т. Д. Другими словами, «объединить маленьких искателей в один большой битмап» не применимо, по крайней мере, не наивно.
Pattern 0: The Hack
ли объединить маленькие педерасты в растровое изображение и использовать его в качестве фона (как рисунок контекст?). Наложите это на изображения с пустым содержимым, которое будет обрабатывать хиты, контекстные меню, события и т. Д.
Преимущество в том, что мы говорим только о двух растровых изображениях здесь: отображаемый в данный момент и тот, который должен его заменить. Это должно быть очень быстро. Однако мой многолетний опыт повышает красный флаг опасности. Ваши комментарии?
Узор 1: уменьшить размер изображения
Это не легкая задача, когда вы заранее знаете размер изображения, чтобы изменить размер, чтобы, и когда вы будете готовы потерять детали (цвет) для выполнения:
- Уменьшение размера растрового изображения с помощью BitmapImage.DecodePixelWidth
- уменьшить цветовую информацию, используя FormatConvertedBitmap.DestinationFormat
- Установить поведение масштабирования элемента управления с etting Image.Stretch to Stretch.None
- Установите SetBitmapScalingMode для изображения в LowQuality.
- замораживать мудак
См код here.
Pattern 2: Фон упреждающего
Эта модель применима, когда вы думаете, вы можете воспользоваться пользователем глядя на изображения на экране, а также подготовить вперед следующие изображения для отображения. Недостатки для вашего проекта, в дополнение к издержкам на память, заключаются в том, что он должен поддерживать цель .Net Framework 4, а не только профиль клиента, поэтому может потребоваться установка на клиентском компьютере. Вам самому придется страдать от асинхронного программирования.
В этом шаблоне вы создаете точно необходимое количество элементов управления изображением. Когда необходимо добавить, перемещать или удалять растровые изображения, вы изменяете только BitmapSource (ы) элементов управления Image. Задача BackgroundWorker отвечает за предварительную выборку BitmapSource (ов) (возможно, используя шаблон «Уменьшить размер изображения» выше) и вставляя их в MemoryCache.
Для этого вам необходимо установить CacheOption BitmapImage в OnLoad, чтобы работа была загружена фоновым рабочим.
Узор 3: Рисунок Контекст
Это было предложено Шелдон Ziao от поддержки Microsoft на форуме MSDN WPF here. См. Стр. 494, глава 15 «2D-графика» в WPF 4 Адама Натана. Развязано для описания DrawingContext. Я не могу сказать, что понимаю. Согласно ответу here, я предполагаю, что это улучшит обработку чертежей геометрии, а не растровых изображений. Затем я не думаю, что это будет поддерживать требования к фокусу и событиям для изображений (мое плохое для того, чтобы не объяснять требования лучше на форуме). Кроме того, меня беспокоит сводное предложение книги: «Обратите внимание, что использование DrawingContext не изменяет тот факт, что вы работаете в системе с сохраненным режимом. Указанный рисунок не выполняется немедленно; команды сохраняются WPF до тех пор, пока они не понадобятся ». Это означает, что после нашего четного обработчика мы не можем использовать параллелизм, как в« Предварительной выборке фона ».
Узор 4: Writeable Bitmaps
В документации MSDN here описывает это как двойной буферной системы: Ваш UI поток обновляет буфер; поток рендеринга WPF перемещает это в видеопамять.
Предполагаемое использование (см. here) предназначено для растровых изображений, которые очень сильно изменяются в видеоролике, таком как дисплей. Я не уверен, но, возможно, это можно взломать и объединить с шаблоном Pre-fetch Background и использовать в сценарии сетки.
Pattern 5: Сохраненная Bitmap
Не так много информации на MSDN (here). В архиве форума WPF (here) объясняется, что «BitmapCache API предназначен для кэширования вашего содержимого (при рендеринге в аппаратном обеспечении) в видеопамяти, то есть он остается на вашем GPU. Это экономит вам стоимость повторного рендеринга этого контента при рисовании его на экране. «Это кажется отличной идеей. Однако я не уверен, каковы подводные камни и как их использовать.
шаблон 6: RenderTargetBitmap
RenderTargetBitmap преобразует Визуальная в растровое изображение. Я не уверен, имеет ли это значение здесь. См. here.
Редактировать: Что касается вопроса Пола Хёнеке: Я написал, что «Мое приложение должно отображать множество битмапов». Я не заметил, что мне нужно отображать около 800 изображений одновременно.
можно прочитать о проблемах производительности, участвующих в моих С.О. вопросы WPF Bitmap performance и How can I make displaying images on WPF more “snappy”?
Я изменил описание рисунка 1, чтобы выделить концепцию, что элементы управления изображения не созданы или удалены (если мы не хотим для отображения большей или меньшей сетки). Только их источники установлены в разные, новые или нулевые источники Bitmap.
Редактировать: This question as posted on the WPF support forum, с некоторыми ответами персонала MS.
Сколько изображений вы ожидаете? Я сделал приложение, которое показывает сетку тысяч изображений раньше. Мы использовали список виртуального режима; по мере того, как пользователь прокручивается вниз, изображения загружаются в фоновый поток, застывают и устанавливаются на источник изображения. Ясно, что вы много думали об этом ... но, возможно, знать больше о том, чего вы хотите добиться, было бы лучше. Например, какие проблемы у вас возникли, чтобы оптимизировать такой приоритет? –
@PaulHoenecke Привет, Пол, благодарю вас за ответ. Виртуальные коллекции помогают вам, когда вы хотите отобразить небольшое количество элементов из большой коллекции. Здесь я хочу отображать около 1K элементов одновременно. Кроме того, я не уверен, что существует виртуализованная сетка. Наконец, шаблон 1 по существу виртуализуется - я добавлю en edit. – Avi
Ави, ваш вопрос выглядит неуместным для описанной проблемы. По какой-то причине вы можете улучшить коэффициент сжатия, но тогда вам нужно точно знать, какие изображения вы показываете. Или, с другой стороны, вы можете захотеть дать пользователю представление обо всех доступных изображениях, тогда вы можете определить некоторые наборы и отобразить миниатюры или аналогичные. Но обе вещи не обязательно связаны друг с другом. Может быть, вы хотите что-то похожее на метрику сходства для определения наборов похожих изображений? –