В GDI + произошла общая ошибка - PullRequest
0 голосов
/ 19 декабря 2011

Я получаю сообщение об ошибке «Произошла общая ошибка в GDI +» в моем примере кода ниже. То, что я делаю, - это то, что я делаю запрос, чтобы получить ответ для многих файлов JPEG, доступных на живом сайте. Когда я получаю ответ, я сохраняю файл в локальной папке моего приложения и преобразование этих изображений в двоичный файл (байты массива), чтобы я мог сохранить его в базе данных.

private byte[] GetBinaryImageData(string imgURL)
{
    HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(imgURL);
    WebResponse response = Request.GetResponse();
    Stream str = response.GetResponseStream();
    System.Drawing.Image objTempImg = System.Drawing.Image.FromStream(str);
    objTempImg.Save(FileName, ImageFormat.Jpeg);

    FileStream fileStream = new FileStream(FileName, FileMode.Open, FileAccess.Read);
    byte[] buffer = new byte[fileStream.Length];
    fileStream.Read(buffer, 0, (int)fileStream.Length);
    fileStream.Close();
    return buffer;
}

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

Ответы [ 2 ]

2 голосов
/ 19 декабря 2011

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

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

Из связанной статьи:

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

Чтобы сохранить доступ к исходным битам, GDI + блокирует любой исходный файл и вынуждает приложение поддерживать срок службы любого исходного потока в течение срока службы растрового изображения или объекта изображения.

2 голосов
/ 19 декабря 2011

Если бы мне пришлось угадывать;иногда возникают проблемы с ручками по той причине, что вы неправильно утилизируете вещи .Это особенно важно для таких вещей, как GDI +.Введите несколько using операторов в ваш код, поскольку в значительной степени все из этих объектов IDisposable:

HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(imgURL);
using(WebResponse response = Request.GetResponse())
using(Stream str = response.GetResponseStream())
using(System.Drawing.Image objTempImg = System.Drawing.Image.FromStream(str))
{
    objTempImg.Save(FileName, ImageFormat.Jpeg);
}
return File.ReadAllBytes(FileName);

(заметьте, я также изменил ваш код чтения файлов, так какэто было невероятно ненадежно; неправильно предполагать, что Stream.Read фактически читает все данные; вы должны проверить возвращаемое значение и выполнить цикл; но поскольку вы хотите всего этого, File.ReadAllBytes проще).

...