Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 加载、保存然后再次加载图像会抛出“GDI+中发生一般错误”_C#_Image_Gdi+ - Fatal编程技术网

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

C# 加载、保存然后再次加载图像会抛出“GDI+中发生一般错误”,c#,image,gdi+,C#,Image,Gdi+,这个。我记得有一段时间我用不同的代码得到了它,但它回来了,带着复仇的心情,但是用了一些我似乎无法理解的新代码。 这肯定是通用的 目标 我正在尝试构建一个表单,允许用户: 选择一个图像。 按save关闭表单,并将图像保存到数据库中的字节[]。 打开从字节[]加载图像的窗体。 允许他们再次按save。 允许他们再次打开表单,再次显示图像。 一个非常标准的加载/保存场景 问题 加载和保存到SQL Server时,一切正常。我遇到的问题是,即使我使用相同的设置,也会反复加载和保存到byte[]或从byt

这个。我记得有一段时间我用不同的代码得到了它,但它回来了,带着复仇的心情,但是用了一些我似乎无法理解的新代码。 这肯定是通用的

目标 我正在尝试构建一个表单,允许用户:

选择一个图像。 按save关闭表单,并将图像保存到数据库中的字节[]。 打开从字节[]加载图像的窗体。 允许他们再次按save。 允许他们再次打开表单,再次显示图像。 一个非常标准的加载/保存场景

问题 加载和保存到SQL Server时,一切正常。我遇到的问题是,即使我使用相同的设置,也会反复加载和保存到byte[]或从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;
    }
}
该错误是GDI+中发生的一般错误。在第二次将图像再次保存到MemoryStream时抛出。我通过检查第一次保存之前和第二次保存之前的值,检查了这与RawFormat无关:

1st Save : {b96b3cae-0728-11d3-9d7b-0000f81ef32e}
2nd Save : {b96b3cae-0728-11d3-9d7b-0000f81ef32e}
这些值是相同的,因此丢失ImageFormat信息不会有问题


有人能帮忙调试这个问题吗?我使用的代码示例使用JPEG进行了测试。

我最近遇到了我认为是相同的问题。您需要在创建MemoryStream时跳过using语句。创建位图会保留对创建位图的流的引用。你可以在网上看到


切勿破坏创建系统图形对象的基础流。保留所有源流,防止它们超出范围。这包括任何字节数组。如果您不能避免丢失原始流的范围,请考虑使用Stask.ARay.Apple来复制底层字节数组的干净副本,这些字节数组可以用来重新组成流,从而重新构成图像。p> 阅读本文: 注意症状和原因。忽略变通方法段落,它是无用的。

看看:
如果流在位图对象的生命周期内被破坏,则无法成功访问基于流的图像

哦,我的。。。谢谢你。我发现了你提到的一点:你不能破坏这条流。当向位图或图像类构造函数提供流时,GDI+可能会将从流的读取延迟到以后。这意味着您必须在销毁位图或图像对象之后才能销毁流。如果在销毁流后尝试使用位图或图像对象,可能会收到错误消息。应用程序的责任是确保流在新图像对象的生命周期中可以使用。我需要构建一些聪明的流管理,这比您的示例提供的要多。我可不想让那条小溪漂流而不被处理!
private static Bitmap LoadImageFromBytes(byte[] bytes)
{
    var imageStream = new MemoryStream(bytes))
    var image = (Bitmap)Bitmap.FromStream(imageStream);
    return image;
}