Я нашел несколько шаблонов для оптимизации обработки битмапов в WPF. Однако я не понимаю, когда использовать каждый образец. Поскольку я думаю, что это распространенная проблема, я подытожил то, что я понимаю, и что я думаю, и прошу вас о помощи. Если вы можете добавить шаблоны, объясните , как они отличаются, объясните, используют ли они ЦП или графический процессор, и научите , когда использовать каждый и , как их объединить, это будет огромная помощь!
Контекст - Сценарий "Сетка" изображений:
Мое приложение должно отображать много растровых изображений. Изображения отображаются на экране в сетчатой структуре строк и столбцов (не обязательно в классах Grid или UniformGrid, думайте о просмотре Album Media Players Album). Изображения могут перемещаться между различными ячейками сетки. Некоторые изображения в произвольных ячейках могут быть заменены другими. Изображения должны быть интерактивными, содержать контекстное меню, выбирать, перетаскивать и т.д. Другими словами, "объединить маленьких искателей в один большой битмап" не применимо, по крайней мере, не наивно.
Образец 0: Хак
Соедините маленьких искателей с растровым рисунком (как рисовать контекст?) и используйте это как фон. Наложите это на изображение с пустым содержимым, которое будет обрабатывать хиты, контекстные меню, события и т.д.
Преимущество состоит в том, что мы говорим только о двух растровых изображениях здесь: в настоящее время отображается один и тот, который должен его заменить. Это должно быть очень быстро. Однако мой многолетний опыт повышает красный флаг опасности. Ваши комментарии?
Шаблон 1: Уменьшить размер изображения
Это неудобно, когда вы заранее знаете размер изображения для изменения размера и когда вы готовы потерять детали (цвет) для производительности:
- Уменьшить размер растрового изображения с помощью BitmapImage.DecodePixelWidth
- Уменьшить информацию о цвете с помощью FormatConvertedBitmap.DestinationFormat
- Задайте настройку поведения масштабирования элементов управления. Image.Stretch to Stretch.None
- Установите SetBitmapScalingMode для изображения в LowQuality.
- Заморозить bugger
Смотрите код здесь.
Шаблон 2: предварительная выборка фона
Этот шаблон применим, если вы считаете, что можете воспользоваться преимуществами пользователя, смотрящего на изображения на экране, и подготовьте вперед следующие изображения для отображения. Недостатки вашего проекта в дополнение к издержкам на память заключаются в том, что он должен поддерживать цель .Net Framework 4, а не только профиль клиента, поэтому может потребоваться установка на клиентах. Вам самому придется страдать от асинхронной боли программирования.
В этом шаблоне вы создаете точно необходимое количество элементов управления Image. Когда необходимо добавить, перемещать или удалять растровые изображения, вы изменяете только BitmapSource элементов управления Image. Задача BackgroundWorker отвечает за предварительную выборку BitmapSource (ов) (возможно, используя шаблон "Уменьшить размер изображения" выше) и вставляя их в MemoryCache.
Для этого вам нужно установить BitmapImages CacheOption в OnLoad, чтобы работа была загружена фоновым рабочим.
Рисунок 3: Контекст рисования
Это было предложено Шелдоном Цяо из Microsoft Support на форуме MSDN WPF здесь. См. Стр. 494, глава 15 "2D-графика" в Adam Nathans WPF 4 Развязано для описания DrawingContext. Я не могу сказать, что понимаю. В соответствии с ответом здесь, я бы предположил, что это улучшит обработку чертежей геометрии, а не растровых изображений. Затем я не думаю, что это будет поддерживать требования к фокусу и событиям для изображений (мое плохое для того, чтобы лучше не объяснять требования на форуме). Кроме того, Im обеспокоен предложением книги: "Обратите внимание, что использование DrawingContext не меняет факт что вы работаете в системе с сохраненным режимом. Указанный рисунок не происходит сразу, команды сохраняются WPF до тех пор, пока они не понадобятся". Это означает, что после нашего четного обработчика мы не можем воспользоваться parallelism, как в "Предварительной выборке фона".
Рисунок 4: Записываемые растровые изображения
Документация MSDN здесь описывает его как двойную буферную систему: ваш поток пользовательского интерфейса обновляет буфер; WPFs render thread перемещает это в видеопамять.
Предполагаемое использование (см. здесь) для растровых изображений, которые сильно меняются в видеоролике, таком как дисплей. Я не уверен, но возможно, что это можно взломать и объединить с фоном Pre-fetch pattern и использовать в сценарии сетки.
Шаблон 5: Кэшированный растровый рисунок
Немного информации о MSDN (здесь). В архиве форума WPF (здесь) объясняется, что "BitmapCache API предназначен для кэширования вашего содержимого (при рендеринге в аппаратном обеспечении) в видеопамяти, что означает, что он остается на вашем GPU, что экономит вам стоимость повторного рендеринга этого контента при его рисовании на экране". Это кажется отличной идеей. Я не уверен, однако, каковы подводные камни и способы их использования.
Шаблон 6: RenderTargetBitmap
RenderTargetBitmap преобразует Visual в растровое изображение. Я не уверен, если это имеет значение здесь. См. здесь.
Изменить. Что касается вопроса Павла Хонекека: я написал, что "Мое приложение должно отображать множество битмапов". Я не заметил, что мне нужно отображать около 800 изображений одновременно.
Можно прочитать о проблемах производительности, связанных с моими вопросами SO WPF Bitmap performance и Как сделать отображение изображений на WPF более "мгновенный" ?
Я изменил описание шаблона 1, чтобы подчеркнуть концепцию, что элементы управления изображением не создаются и не удаляются (если мы не хотим отображать большую или меньшую сетку). Только их источники установлены в разные, новые или нулевые источники Bitmap.
Изменить: Этот вопрос опубликован на форуме поддержки WPF с некоторыми ответами персонала MS.