Есть ли более производительная альтернатива ImageList.Images.Add? - PullRequest
1 голос
/ 27 июня 2009

У меня есть winforms ImageList, который содержит 200 256x256 изображений.

Когда я добавляю изображения, 1 к половине времени программы тратится на метод Add согласно профайлеру ANTS .NET.

Таким образом, запуск программы занимает 10 секунд, а 5 тратится там. На мой взгляд, это очень медленно.

Я реализовал то же самое, используя ImageList.Images.AddRange. Результат не изменился.

Кто-нибудь знает какие-либо альтернативы или оптимизации для решения этой проблемы? WPF ImageList быстрее? Есть ли более быстрые формы ImageList?


EDIT:

foreach (string imageFile in images)
{
    imageList.Images.Add(Image.FromFile(imageFile)); // takes pretty much all of program's execution time.
}

Ответы [ 4 ]

2 голосов
/ 28 июня 2009

Посмотрите на альбом и список в PhotoSuru , одном из примеров приложений Microsoft WPF. У них есть несколько разных экранов просмотра миниатюр, которые загружаются довольно быстро (все изображения загружаются асинхронно, и загружаются только необходимые изображения). И есть полный исходный код, чтобы вы могли начать, если это то, что вы ищете.

Это не совсем похоже на Picasa (они решили только показывать полные ряды фотографий вместо частично покрытого ряда, как Picasa), но реализовали собственную виртуализирующую панель IScrollInfo (достаточно просто, и у Бен Констебля есть замечательная серия постов на нем ), вы сможете получить желаемую производительность и желаемое поведение.

Последнее замечание. Возможно, вы уже делаете это (хранятся ли ваши изображения как изображения размером 256x256 пикселей?), Но всякий раз, когда вы пытаетесь отобразить миниатюры изображений, вам не следует загружать полное изображение. Чтение 2 МБ + файлов изображений с диска только для рендеринга целых экранных миниатюр размером 256x256 пикселей всегда имеет больший выигрыш в производительности, чем чтение небольшого уменьшенного изображения соответствующего размера. Если вы можете, кэшируйте миниатюры где-нибудь (как это делают Windows и Picasa) или, по крайней мере, попробуйте использовать встроенные миниатюры в любых файлах JPEG, с которыми вы сталкиваетесь.

1 голос
/ 28 июня 2009

Используете ли вы ListView для пользовательского интерфейса, использующего этот ImageList?

Общее решение подобных проблем - загрузить только некоторые изображения, потому что только некоторые из них отображаются одновременно, а затем загрузить другое по мере необходимости. ListView имеет свойство VirtualMode для таких сценариев.

Загрузка и добавление 200 изображений одновременно может оказаться слишком сложной задачей, вы можете загрузить первые показанные изображения, а затем использовать фоновый поток для загрузки других. Посмотрите, как в Win7 отображаются изображения: при прокрутке отображается некоторая метка-заполнитель, а затем, когда изображение загружено, отображается реальная картинка. Имейте в виду, что это не простая вещь , чтобы сделать.

0 голосов
/ 13 марта 2016

Да, это так. Загрузить изображения в List<Image>. Затем позвоните ImageList.Images.AddRange(list).

List<Image> list = new List<Image>();
foreach (string imageFile in images)
{
    list.Add(Image.FromFile(imageFile)); 
}
imageList.Images.AddRange(list.ToArray());
0 голосов
/ 24 ноября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...