简体   繁体   中英

Generic error occurred in GDI+

I am getting the error "Generic error occurred in GDI+" in my sample code below. What I do is that I make a request to get response for many jpeg files available at live site. When I get response, I save the file to my application's local folder and converting these images to binary (bytes of array) so that I can save it into database.

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;
}

i don't get this error for all images, but it occurs for some of images. Anybody know the solution? I have already spent 2 days to oversome this

If I had to guess; it is having problems with handles occasionally, for the reason that you aren't disposing things correctly . This is especially important for things like GDI+. Introduce a few using statements to your code, since pretty much all of those objects are 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);

(note I changed your file-reading code too, since it was hugely unreliable; it is incorrect to assume that Stream.Read actually reads all the data; you are supposed to check the return value and loop; but since you want it all, File.ReadAllBytes is easier).

Judging by this article it appears the stream the image is loaded from must exist for the lifetime of the image or bad things can happen.

I've run into this from time to time and found it easiest to copy the image data to a memory stream or a file my process controls and construct the image from that.

From the linked article:

GDI+, and therefore the System.Drawing namespace, may defer the decoding of raw image bits until the bits are required by the image. Additionally, even after the image has been decoded, GDI+ may determine that it is more efficient to discard the memory for a large Bitmap and to re-decode later. Therefore, GDI+ must have access to the source bits for the image for the life of the Bitmap or the Image object.

To retain access to the source bits, GDI+ locks any source file, and forces the application to maintain the life of any source stream, for the life of the Bitmap or the Image object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM