Image.FromFile очень медленный. Любые альтернативы, оптимизации? - PullRequest
4 голосов
/ 27 июня 2009

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

Я использую метод Images.FromFile для загрузки изображений, а затем добавляю их в список изображений.

Согласно профайлеру ANTS .NET, половина времени программы тратится на Images.FromFile. Есть ли лучший способ загрузить изображение для добавления в список изображений?

Еще одна вещь, которая может быть оптимизирована, это то, что загружаемые изображения больше 256x256. Так есть ли способ загрузить их, сначала изменив их размер или что-то в этом роде? Я просто хочу равномерно масштабировать их, если их высота превышает 256 пикселей.

Есть идеи по оптимизации?

РЕДАКТИРОВАТЬ: Это JPEG.

Ответы [ 7 ]

3 голосов
/ 24 ноября 2009

Вы не говорите, насколько больше, чем 256x256 изображений на самом деле - изображения современных цифровых камер намного больше, чем это.

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

Тогда вы можете решить, есть ли небольшая проблема 'Image.FromFile' или простая 'вот как медленно работает мой компьютер / диски / антивирусный сканер / сеть'.

Простым тестом базовой производительности файлового ввода-вывода было бы сделать File.ReadAllBytes () для каждого изображения вместо Image.FromFile () - это скажет вам, какая часть времени была потрачена на диск и что с обработкой изображений - я подозреваю, что вы обнаружите, что в основном это диск, и в этот момент ваш единственный шанс ускорить его может быть одним из методов получения миниатюр JFIF из файлов. Или, может быть, можно представить умные вещи с частичным чтением прогрессивных JPEG-файлов, хотя я не знаю, делает ли кто-нибудь это, и не являются ли ваши файлы прогрессивными (вероятно, нет).

Я действительно не знаю, как быстро вам нужно их загружать, но если проблема заключается в том, что во время загрузки файлов зависает интерактивное приложение, подумайте, как сделать это лучше для пользователя - возможно, используйте BackgroundWorker. чтобы загрузить их асинхронно, возможно, отсортируйте изображения по возрастанию размера файла и загрузите сначала маленькие для лучшей субъективной производительности.

2 голосов
/ 02 декабря 2012

Вы можете использовать F reeImage.NET , который отлично подходит для загрузки изображений на фоне.

Image.FromFile содержит скрытый Mutex, который блокирует ваше приложение, если вы пытаетесь загрузить большие изображения даже в фоновом потоке.

Что касается JPEG, библиотека FreeImage использует библиотеку OpenJPEG, которая может загружать изображения JPEG в меньшем масштабе быстрее. Он также может использовать встроенные миниатюры.

Классы WPF также позволяют загружать изображения в меньшем разрешении, но это нельзя использовать, если вы ограничены WinForms.

2 голосов
/ 24 ноября 2009

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

1 голос
/ 25 ноября 2009

У меня есть список изображений winforms

Я бы не использовал ImageList в этом сценарии. Внутренне, это старый общий элемент управления Windows, предназначенный для работы с иконками GUI, обычно 32x32 пикселей или меньше.

Еще одна вещь, которая может быть оптимизирована, это то, что загружаемые изображения имеют размер больше 256x256.

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

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

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

Похоже, вам нужны какие-то эскизы изображений? Не забывайте, что изображения в формате JPEG уже содержат миниатюры внутри, так что вы можете извлечь только это маленькое изображение и вам не нужно масштабировать. Такие изображения, однако, меньше, чем 256x256.

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

1 голос
/ 28 июня 2009
  1. Если вам нужна скорость, то предварительно масштабируйте изображения, не делайте этого во время выполнения.
  2. Вы не упомянули нужный тип загружаемых вами изображений (jpeg, png, gif, bmp), конечно, что bmp является самым быстрым, поскольку он не имеет (или почти не имеет) сжатия.
  3. Ваши изображения поддерживают 256 цветов (8 бит с палитрой), bmp, gif и png, и этот формат может загружаться довольно быстро.
0 голосов
/ 17 октября 2013

Это может быть слишком поздно, но использование свойства ImageLocation сделает две вещи

  1. ускорение загрузки изображения

  2. обойти ошибку ( Файл изображения блокируется, если для свойства PictureBox Image установлено значение )

    pictureBox1.ImageLocation = "image.jpg";
    
    pictureBox1 .SizeMode =  PictureBoxSizeMode.StretchImage;
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...