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