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

时间:2010-02-03 15:54:15

标签: c# image gdi+

seems to be in infamous error。我记得在不久的代码中找到了一段时间,但它回来了,带着报复,但是有一些我似乎无法弄清楚的新代码。
肯定是generic肯定!{/ p>

目标

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

  1. 选择图像。
  2. 按保存(关闭表单),然后将图像保存到byte[]数据库中。
  3. 打开表单(从byte[]加载图片)。
  4. 允许他们再次按“保存”。
  5. 允许他们再次打开表单,再次显示图像。
  6. 非常标准的加载/保存方案。

    问题

    关于加载和保存到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

    值相同,因此丢失{{1}}信息不会有问题。

    任何人都可以帮助调试此问题吗?我使用的代码示例使用JPEG和you can get it here进行测试。

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

阅读本文:http://support.microsoft.com/kb/814675 (注意症状和原因段落。忽略变通方法段落它没用。)

答案 2 :(得分:0)

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