Загрузка изображения и зависимость потока / файла - PullRequest
2 голосов
/ 03 февраля 2012

Прямо сейчас у меня есть приложение, которое загружает кучу миниатюр изображений в элементы управления PictureBox.Иногда более ста одновременно.Изображения создаются с использованием Image.FromStream (MemoryStream), и поток памяти представляет каждый файл JPG.

В настоящее время, как только я вызываю Image.FromStream, я назначаю ссылку на блок изображения, а затем немедленнопосле того, как я Flush () и Dispose () поток.

Согласно документации, я не должен освобождать поток, пока я не закончу с изображением.Тем не менее, у меня не было ошибок при этом.Мои элементы управления PictureBox могут перекрашивать себя в течение всего дня с помощью миниатюрных изображений, даже после того, как потоки памяти были долго удалены.

Однако, если я пытаюсь получить доступ к этим изображениям любым способом, например, вызывая функцию Save,выдает ошибку.

  • Если растровое изображение имеет зависимость от потока памяти или потока файлов, будет ли оно уничтожать источник при его удалении?Или это только когда он сам создает поток с помощью Bitmap.FromFile?

  • Утилизация MemoryStream сразу же, как я считаю, считается нормально?PictureBox должен каким-то образом кэшировать изображение.У меня никогда не было ошибки, потому что мне не нужно прикасаться к изображению после его установки.

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

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

Есть ли хороший способ заставить изображение быть предварительно загруженным?Каковы расхождения между Image.FromFile, Image.FromStream, новым растровым изображением (fileName) и т. Д.?Загружает ли какой-либо из них все байты сразу или он задерживается до тех пор, пока они не понадобятся в первый раз?

Вот мой код:

MemoryStream ms = new MemoryStream(bytes); // byte[] array
pictureBox.Image = Image.FromStream(ms);
ms.Flush();
ms.Dispose();

Ответы [ 2 ]

1 голос
/ 04 февраля 2012

GDI +, который лежит в основе классов Image, требует, чтобы исходный поток оставался открытым, пока изображение существует для правильной работы. Также плохая идея записывать изменения в исходный поток, пока Image его использует. Изменения должны быть сохранены в другом потоке.

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

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

Кроме того, вызов Flush on the Stream имеет смысл только в том случае, если в Stream записана запись.

Если вы хотите улучшить поведение пользовательского интерфейса для ваших PictureBox, попробуйте это:

  1. Установить InitialImage для маленького вращающегося GIF.
  2. Установите для параметра WaitOnLoad значение false.
  3. Укажите изображение, установив ImageLocation. (Вы можете использовать спецификацию файла или URL в нем.)
  4. Загрузка изображений асинхронно с использованием метода LoadAsync.
0 голосов
/ 03 февраля 2012

1)

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

Взгляните на Метод Image.FromStream (Stream, Boolean) :

Вы должны держать поток открытым в течение всего времени жизни изображения.

2)

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

Вам просто не следует не утилизировать экземпляр Image, так как он был назначен наPictureBox (т. Е. Используется графический ящик) и , в то время как PictureBox использует его .В противном случае PictureBox попытается использовать удаленное изображение, что приведет к некоторым «нехорошим» последствиям.

PictureBox.Image Свойство :

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

Обновление:

Пример практически с тем же сценарием: КАК: Копироватьизображения из базы данных непосредственно в элемент управления PictureBox с помощью Visual C # .

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