Подтвердить что ты не робот

Загрузка изображения из потока без сохранения потока

Можно ли использовать метод FromStream для System.Drawing.Image, не сохраняя поток открытым для срока службы изображения?

У меня есть приложение, которое загружает кучу графики панели инструментов из файлов ресурсов, используя комбинацию Image.FromStream и Assembly.GetManifestResourceStream.

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

После загрузки стрижки я, наконец, проследил его до начальной загрузки изображения. Разумеется, если я создам любой объект, реализующий IDisposable, который также будет уничтожен в том же методе, я завершу его в оператор using, например

using (Stream resourceStream = assembly.GetManifestResourceStream(resourceName))
{
   image = Image.FromStream(resourceStream);
}

Если я удаляю оператор using, чтобы поток не был удален, приложение больше не вылетает на XP. Но у меня теперь есть куча "сиротских" потоков, которые висят - изображения хранятся в командных классах, и они правильно удаляют изображения, когда они сами расположены, но исходный поток не является.

Я проверил документацию для FromStream и подтверждает, что поток должен оставаться открытым. Почему это не разбилось и не сгорело в системе разработки Windows 7, однако это загадка!

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

Возможно ли создать изображение, а затем убить поток там?

4b9b3361

Ответ 1

Причина, по которой поток должен быть открыт, - следующий:

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

Задокументированное обходное решение - создать либо неиндексированное изображение с помощью Graphics.DrawImage, либо создать индексированный Bitmap из исходного изображения, как описано здесь:

зависимости растрового изображения и изображения

Ответ 2

Согласно документации Image.FromStream, поток должен оставаться открытым во время использования изображения. Поэтому, даже если закрытие работает (и нечего сказать, что вы не можете закрыть поток до его размещения, поскольку сам объект потока), это может быть не очень надежный подход.

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

Ответ 3

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