Image.Save(..) 抛出一个 GDI+ 异常,因为内存流已关闭
我有一些二进制数据,我想将其保存为图像。 当我尝试保存图像时,如果用于创建图像的内存流在保存之前已关闭,则会引发异常。 我这样做的原因是因为我正在动态创建图像,因此..我需要使用内存流。
这是代码:
[TestMethod]
public void TestMethod1()
{
// Grab the binary data.
byte[] data = File.ReadAllBytes("Chick.jpg");
// Read in the data but do not close, before using the stream.
Stream originalBinaryDataStream = new MemoryStream(data);
Bitmap image = new Bitmap(originalBinaryDataStream);
image.Save(@"c:\test.jpg");
originalBinaryDataStream.Dispose();
// Now lets use a nice dispose, etc...
Bitmap2 image2;
using (Stream originalBinaryDataStream2 = new MemoryStream(data))
{
image2 = new Bitmap(originalBinaryDataStream2);
}
image2.Save(@"C:\temp\pewpew.jpg"); // This throws the GDI+ exception.
}
有人对如何在关闭流的情况下保存图像有任何建议吗? 我不能指望开发人员记得在保存图像后关闭流。 事实上,开发人员不知道图像是使用内存流生成的(因为它发生在其他地方的其他代码中)。
我真的很困惑:(
i've got some binary data which i want to save as an image. When i try to save the image, it throws an exception if the memory stream used to create the image, was closed before the save. The reason i do this is because i'm dynamically creating images and as such .. i need to use a memory stream.
this is the code:
[TestMethod]
public void TestMethod1()
{
// Grab the binary data.
byte[] data = File.ReadAllBytes("Chick.jpg");
// Read in the data but do not close, before using the stream.
Stream originalBinaryDataStream = new MemoryStream(data);
Bitmap image = new Bitmap(originalBinaryDataStream);
image.Save(@"c:\test.jpg");
originalBinaryDataStream.Dispose();
// Now lets use a nice dispose, etc...
Bitmap2 image2;
using (Stream originalBinaryDataStream2 = new MemoryStream(data))
{
image2 = new Bitmap(originalBinaryDataStream2);
}
image2.Save(@"C:\temp\pewpew.jpg"); // This throws the GDI+ exception.
}
Does anyone have any suggestions to how i could save an image with the stream closed? I cannot rely on the developers to remember to close the stream after the image is saved. In fact, the developer would have NO IDEA that the image was generated using a memory stream (because it happens in some other code, elsewhere).
I'm really confused :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
因为它是一个 MemoryStream,所以您实际上不需要关闭该流 - 如果您不关闭流,也不会发生什么不好的事情,尽管显然处置任何一次性的东西是一个很好的做法。 (有关此问题的更多信息,请参阅此问题。)
但是,您应该处理位图 - 并且将为您关闭流。 基本上,一旦您为位图构造函数提供了一个流,它就“拥有”该流,并且您不应该关闭它。 正如该构造函数的文档所说:
我找不到任何承诺在处置位图时关闭流的文档,但您应该能够相当容易地验证这一点。
As it's a MemoryStream, you really don't need to close the stream - nothing bad will happen if you don't, although obviously it's good practice to dispose anything that's disposable anyway. (See this question for more on this.)
However, you should be disposing the Bitmap - and that will close the stream for you. Basically once you give the Bitmap constructor a stream, it "owns" the stream and you shouldn't close it. As the docs for that constructor say:
I can't find any docs promising to close the stream when you dispose the bitmap, but you should be able to verify that fairly easily.
GDI+ 中发生一般错误。
也可能是由于保存路径不正确造成的!
我花了半天才注意到这一点。
因此,请确保您也仔细检查了保存图像的路径。
A generic error occurred in GDI+.
May also result from incorrect save path!
Took me half a day to notice that.
So make sure that you have double checked the path to save the image as well.
也许值得一提的是,如果 C:\Temp 目录不存在,即使您的流仍然存在,它也会抛出此异常。
Perhaps it is worth mentioning that if the C:\Temp directory does not exist, it will also throw this exception even if your stream is still existent.
复制位图。 您必须在位图的生命周期内保持流打开。
绘制图像时:System.Runtime.InteropServices.ExternalException : GDI 中发生一般错误
Copy the Bitmap. You have to keep the stream open for the lifetime of the bitmap.
When drawing an image: System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI
我也遇到了同样的问题,但实际上原因是应用程序没有权限在 C 上保存文件。当我更改为“D:\..”时,图片已保存。
I had the same problem but actually the cause was that the application didn't have permission to save files on C. When I changed to "D:\.." the picture has been saved.
您可以尝试创建位图的另一个副本:
You can try to create another copy of bitmap:
当我尝试使用 Citrix 时,出现了此错误。 图像文件夹设置为服务器中的 C:\,我没有权限。 将图像文件夹移动到共享驱动器后,错误就消失了。
This error occurred to me when I was trying from Citrix. The image folder was set to C:\ in the server, for which I do not have privilege. Once the image folder was moved to a shared drive, the error was gone.
GDI+ 中发生一般错误。 它可能是由于图像存储路径问题而发生的,我收到此错误是因为我的存储路径太长,我通过首先将图像存储在最短路径中并使用长路径处理技术将其移动到正确的位置来解决此问题。
A generic error occurred in GDI+. It can occur because of image storing paths issues,I got this error because my storing path is too long, I fixed this by first storing the image in a shortest path and move it to the correct location with long path handling techniques.
我收到此错误,因为我正在执行的自动化测试试图将快照存储到不存在的文件夹中。 创建文件夹后,错误解决了
I was getting this error, because the automated test I was executing, was trying to store snapshots into a folder that didn't exist. After I created the folder, the error resolved
一种奇怪的解决方案使我的代码能够工作。
在paint中打开图像并将其另存为具有相同格式的新文件(.jpg)。 现在尝试使用这个新文件,它可以工作。 它清楚地向您解释该文件可能以某种方式损坏。
仅当您的代码修复了所有其他错误时这才有帮助
One strange solution which made my code to work.
Open the image in paint and save it as a new file with same format(.jpg). Now try with this new file and it works. It clearly explains you that the file might be corrupted in someway.
This can help only if your code has every other bugs fixed
当我尝试将图像保存到路径
C:\Program Files (x86)\some_directory
且
.exe
未执行运行时, 它也出现在我身上作为管理员,我希望这可以帮助也有同样问题的人。It has also appeared with me when I was trying to save an image into path
C:\Program Files (x86)\some_directory
and the
.exe
wasn't executed to run as administrator, I hope this may help someone who has same issue too.对我来说,下面的代码崩溃了,并在保存到
MemoryStream
的行上发生了GDI+中发生一般错误
。 该代码在 Web 服务器上运行,我通过停止并启动正在运行该站点的应用程序池来解决该问题。一定是 GDI+ 中出现了一些内部错误
For me the code below crashed with
A generic error occurred in GDI+
on the line which Saves to aMemoryStream
. The code was running on a web server and I resolved it by stopping and starting the Application Pool that was running the site.Must have been some internal error in GDI+
当我在 WPF 应用程序中尝试进行简单的图像编辑时,遇到了此错误。
将图像元素的源设置为位图会阻止文件保存。
即使设置 Source=null 似乎也不会释放该文件。
现在我只是从不使用图像作为图像元素的源,所以我可以在编辑后覆盖!
编辑
在听说 CacheOption 属性后(感谢@Nyerguds)我找到了解决方案:
因此,我必须在设置
CacheOption
BitmapCacheOption.OnLoad
之后设置 Uri,而不是使用 Bitmap 构造函数。(下面的Image1
是 WpfImage
元素)而不是
使用:
请参阅:WPF 图像缓存
I came across this error when I was trying a simple image editing in a WPF app.
Setting an Image element's Source to the bitmap prevents file saving.
Even setting Source=null doesn't seem to release the file.
Now I just never use the image as the Source of Image element, so I can overwrite after editing!
EDIT
After hearing about the CacheOption property(Thanks to @Nyerguds) I found the solution:
So instead of using the Bitmap constructor I must set the Uri after setting
CacheOption
BitmapCacheOption.OnLoad
.(Image1
below is the WpfImage
element)Instead of
Use:
See this: WPF Image Caching
试试这个代码:
Try this code:
我使用图像处理器调整图像大小,有一天我收到“GDI+ 中发生一般错误”异常。
查找了一段时间后,我尝试回收应用程序池,结果成功了。 所以我在这里记下来,希望它有所帮助;)
干杯
I used imageprocessor to resize images and one day I got "A generic error occurred in GDI+" exception.
After looked up a while I tried to recycle the application pool and bingo it works. So I note it here, hope it help ;)
Cheers
今天,当相同的代码在本地和我们的开发服务器上运行良好但在生产服务器上运行良好时,我在服务器上遇到了此错误。 重启服务器解决了。
I was getting this error today on a server when the same code worked fine locally and on our DEV server but not on PRODUCTION. Rebooting the server resolved it.