Image.Save () throws an ExternalException for the image loaded from Stream (Image.FromStream ())

I am tracking an unpleasant problem, and I narrowed down the problem and realized that this happens when I deal with the Image instance returned by Image.FromStream (). I have a utility method that returns an instance of an image from a file using Stream, so I don't have an open file descriptor. Here is this useful method (nothing special):

public static Image ImageFromFileReleaseHandle(string filename) { using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) { return Image.FromStream(fs); } } 

When I try to save an image loaded from the above method, I get InteropServices.ExternalException "A general error occurred in GDI +". The following code example will demonstrate this:

 private void button6_Click(object sender, EventArgs e) { var filename = @"D:\My Documents\My Pictures\2010-03-27 hangover hike.jpg"; // Get an Image instance Image image; using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) { image = Image.FromStream(fs); } // Save to a temp file - this is the code that throws the exception image.Save(Path.GetTempFileName()); } 

If I upload an image using Image.FromFile (), I can save without problems:

 private void button6_Click(object sender, EventArgs e) { var filename = @"D:\My Documents\My Pictures\2010-03-27 hangover hike.jpg"; // Get an Image instance Image image = Image.FromFile(filename); // Save to a temp file - this is the code that throws the exception image.Save(Path.GetTempFileName()); } 

I can not come up with any additional information that would be useful. I hope my code examples are simple enough so you can clearly see the problem.

Thanks Steve

+4
source share
4 answers

try this instead

 // Get an Image instance Image image; using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) { image = Image.FromStream(fs); // Save to a temp file - this is the code that throws the exception image.Save(Path.GetTempFileName()); } 

I think the block used is giving you problems

+1
source

According to the documentation :

You must leave the stream open for the life of the image.

Try calling β€œSave” inside the use block to make sure that no exception is thrown if the stream is still open.

+3
source

Based on the suggestions and comments so far and my own additional reading, I think I have a working solution. Basically the problem is that I cannot close the Stream. Great, but I also can't leave FileStream open without a guarantee that it will close properly.

Instead, I read the file into the buffer, and then create a MemoryStream and pass it to Image.FromStream ().

 var filename = @"D:\My Documents\My Pictures\2010-03-27 hangover hike.jpg"; byte[] imageData = FileUtils.ReadWholeFileBytes(filename); Image image = Image.FromStream(new MemoryStream(imageData)); // dump the buffer to test if this upsets the Memory Stream. I need to read more // about MemoryStream and how it may keep the GC from cleaning up it underlying data imageData = null; // Save to a temp file image.Save(Path.GetTempFileName()); 

Thank you all for your suggestions and questions.

0
source

I have the same problem, but instead of using FileStream , I only have a MemoryStream , because I am loading an image from a database. When I save the image for the first time in the database, everything is fine, but when I update the image in the database, it throws an ExternalException . Here is my code if you want to analyze.

 public class ImageConverter { public static byte[] imageToByteArray(Image imageIn) { if (imageIn == null) return new byte[] { 45 }; using (MemoryStream ms = new MemoryStream()) { imageIn.Save(ms, imageIn.RawFormat); return ms.ToArray(); } } public static Image byteArrayToImage(byte[] byteArrayIn) { if (byteArrayIn == null) return null; using (MemoryStream ms = new MemoryStream(byteArrayIn)) { Image returnImage = Image.FromStream(ms); return returnImage; } } } 
0
source

All Articles