Визуализация многослойного изображения в WPF

61
5

Моя структура данных имеет два поля:

* BackgroundImage (of type Bitmap/Image)
* Points (of type Point2D [])

Мой пример использования: пользователь может загрузить изображение в приложение. После того, как изображение появится на экране пользователя, они могут добавить к нему точки (нажав кнопку мыши). Точки должны быть визуализированы в верхней части изображения, но пользователь должен быть, если нужно, переместить их (например, drag'n'drop).

В настоящий момент я решаю проблему, выполняя следующие действия каждый раз, когда пользователь добавляет/перемещает точку: * клонирует BackgroundImage * рисует все точки на клонированном изображении (используя System.Drawing.Graphics) * возвращает клонированное изображение с точками (выставить его как свойство и связать с изображением в WPF).

Производительность времени этого решения в порядке, однако он потребляет много памяти, так как каждый раз, когда я заканчиваю копирование всего изображения. Мне интересно, есть ли лучший способ сделать это (например, используя слои - тогда мой BackgroundImage остается неизменным все время, пока я продолжаю изменять только верхний слой).

Мой код довольно длинный, но если это нужно, просто дайте мне знать, и я опубликую его.

спросил(а) 2021-01-19T19:19:08+03:00 2 месяца, 3 недели назад
1
Решение
62

когда дело доходит до потребления памяти, нет ничего плохого в описанном выше aproach, если вы убедитесь, что старые экземпляры изображения больше не внедрены, так что GC может их удалить.

Однако во время временных интервалов, в которых клонированное изображение модифицировано, занятие памяти может, разумеется, удваивать минимально возможное значение, если оно не клонируется. Чтобы уменьшить потребление памяти, подвижные точки могут быть реализованы с использованием UIElements. Это также может помочь упростить реализацию, используя WPF hittesting для части "drag'n'drop". Так как UIElements требуют больше памяти, чем точки в BitmapImage, фактическая экономия зависит от отношения точек в битмап-памяти к подвижным точкам.

Чтобы реализовать точки, использующие UIElements, поместите BitmapImage вместе с Canvas в Panel. Затем используйте Canvas в качестве контейнера для точек и установите их позиции, используя прикрепленные свойства Canvas.Top и Canvas.Left. Чтобы заставить точки появляться перед BitmapImage, установите Panel.ZIndex Canvas.

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

ответил(а) 2021-01-19T19:19:08+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема