加载,保存,然后再次加载图像会抛出“GDI +中发生一般错误”

这似乎是臭名昭着的错误 。 我记得在不久的代码中得到了一段时间,但它回来了 ,报复,但有一些我似乎无法弄清楚的新代码。
当然,它绝对是generic

目标

我正在尝试构建一个允许用户执行以下操作的表单:

  1. 选择图像。
  2. 按save(关闭表单),并将图像保存到byte[]到数据库中。
  3. 打开表单(从byte[]加载图像)。
  4. 允许他们再次按保存。
  5. 允许他们再次打开表单,再次显示图像。

一个非常标准的加载/保存方案。

问题

关于加载和保存到SQL Server,一切正常。 我得到的问题是重复加载和保存到byte[]即使我使用相同的设置。 看一下我嘲笑的代码来演示这个问题:

 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 LoadImageFromBytes(byte[] bytes) { using (MemoryStream imageStream = new MemoryStream(bytes)) { Bitmap image = (Bitmap)Bitmap.FromStream(imageStream); return image; } } 

错误A generic error occurred in GDI+. 当第二次将图像再次保存到MemoryStream抛出。 我通过检查第一次保存之前和第二次保存之前的值来检查这与RawFormat

 1st Save : {b96b3cae-0728-11d3-9d7b-0000f81ef32e} 2nd Save : {b96b3cae-0728-11d3-9d7b-0000f81ef32e} 

值是相同的,因此丢失ImageFormat信息不会有问题。

任何人都可以帮助调试此问题? 我使用的代码示例使用JPEG进行测试, 您可以在此处获取 。

我最近认为是同样的问题。 您需要跳过创建MemoryStream的using语句。 创建位图会保留对创建它的流的引用。 您可以在MSDN上阅读它。

 private static Bitmap LoadImageFromBytes(byte[] bytes) { var imageStream = new MemoryStream(bytes)) var image = (Bitmap)Bitmap.FromStream(imageStream); return image; } 

永远不要销毁创建System.Drawing对象的基础流。 保留所有源流,防止它们超出范围。 这包括任何字节数组。 如果您无法避免丢失原始流的范围,请考虑使用System.Array.Copy制作基础字节数组的干净副本,以后可用于重新组合流,从而重新构建图像。

阅读这篇文章: http : //support.microsoft.com/kb/814675 (注意症状和原因段落。忽略Workarounds段落,它没用。)

请查看: https : //support2.microsoft.com/Default.aspx?id = 814675如果在Bitmap对象的生命周期内销毁了流,则无法成功访问基于流的图像。