This seems to be in infamous error. I remember getting it a while back for different code, but it's back, with a vengeance, but with some new code that I can't seem to figure out.
It's definitelygeneric
, for sure!
The Goal
I'm trying to build a form that allows a user to:
- Select an image.
- Press save (which closes the form), and saves the image to a
byte[]
into a database. - Open the form (which loads the image from the
byte[]
). - Allow them to press save again.
- Allow them to open the form again, displaying the image (again).
A pretty standard load/save scenario.
The Problem
Everything works fine regarding loading and saving to the SQL Server. The problem I'm getting is to do with repeatedly loading and saving to and from a byte[]
even though I'm using the same settings. Take a look at this code which I mocked up to demonstrate the problem:
static void Main(string[] args)
{
// Load the image
var initialImage = (Bitmap)Bitmap.FromFile(@"D:\picture.jpg");
// Save to a memory stream and get the bytes
var initialImageBytes = SaveImageToBytes(initialImage);
// Load again from this saved image
Bitmap byteLoadedImage = LoadImageFromBytes(initialImageBytes);
// Save again to bytes, throws "A generic error occurred in GDI+."
var secondaryImageBytes = SaveImageToBytes(byteLoadedImage);
}
private static byte[] SaveImageToBytes(Bitmap image)
{
byte[] imageBytes;
using (MemoryStream imageStream = new MemoryStream())
{
image.Save(imageStream, image.RawFormat);
// "A generic error occurred in GDI+." thrown when saved second time
imageBytes = imageStream.ToArray();
}
return imageBytes;
}
private static Bitmap LoadImageFromByt开发者_Python百科es(byte[] bytes)
{
using (MemoryStream imageStream = new MemoryStream(bytes))
{
Bitmap image = (Bitmap)Bitmap.FromStream(imageStream);
return image;
}
}
The error A generic error occurred in GDI+.
is thrown as the image is saved once more to the MemoryStream
the second time round. I checked this wasn't to do with the RawFormat
by inspecting the value before the first save, and before the second:
1st Save : {b96b3cae-0728-11d3-9d7b-0000f81ef32e}
2nd Save : {b96b3cae-0728-11d3-9d7b-0000f81ef32e}
The values are identical, so it can't be a problem with it losing the ImageFormat
information.
Can anyone help debug this problem? The code sample I used is tested with a JPEG, and you can get it here.
I had what I believe was the same problem recently. You need to skip the using statement around the creation of your MemoryStream. Creating a bitmap keeps a reference to the stream that created it. You can read about it on MSDN.
private static Bitmap LoadImageFromBytes(byte[] bytes)
{
var imageStream = new MemoryStream(bytes))
var image = (Bitmap)Bitmap.FromStream(imageStream);
return image;
}
Never destroy the underlying streams from which your System.Drawing objects were created. Preserve all of your source streams, preventing them from going out of scope. This includes any byte arrays. IF you can't avoid losing scope of your original streams, consider using System.Array.Copy to make clean copies of the underlying byte arrays which can later be used to re-compose your streams and thus re-compose your images.
Read this article: http://support.microsoft.com/kb/814675 (pay attention to the Symptom and Cause paragraphs. ignore the Workarounds paragraph it's useless.)
Take a look at: https://support2.microsoft.com/Default.aspx?id=814675 If the stream was destroyed during the life of the Bitmap object, you cannot successfully access an image that was based on a stream.
精彩评论