我有2个示例代码,我尝试做同样的事情,将属性项更新回图像并将其保存在不同的文件下。
代码1
Image image;
using (FileStream stream = new FileStream(this.fileName, FileMode.Open)) {
image = Image.FromStream(stream);
foreach (var property in this.propItems) {
image.SetPropertyItem(property);
}
}
image.Save(@"D:\Temp\1.jpg");
image.Dispose();
代码2
using (Image image = new Bitmap(this.fileName)) {
foreach (var property in this.propItems) {
image.SetPropertyItem(property);
}
image.Save(@"D:\Temp\1.jpg");
}
唯一的区别是我打开文件的方式。如果我运行第一段代码,我得到了异常消息
System.Runtime.InteropServices.ExternalException未处理
HResult = -2147467259消息= GDI +中发生一般错误 Source = System.Drawing ErrorCode = -2147467259
我的第二段代码运行正常,我可以获得正确的输出。这有什么区别?
答案 0 :(得分:2)
这是设计,Image.FromStream()的MSDN文章严厉警告这一点。关闭流后,图像将不再可用。并且尝试像你一样保存它很可能,但不能保证,当它试图从封闭流中检索像素数据时抛出异常。
Image类的一个关键属性是 lazy ,与许多.NET类不同,它在必要时不会访问流数据。并且在实际使用像素数据之前没有必要,这在您的代码段中的Save()调用中发生。 Kaboom无法再阅读它。
您可以通过使用语句在中移动Save()调用来修复您的第一个代码段:
using (var stream = new FileStream(this.fileName, FileMode.Open))
using (var image = Image.FromStream(stream) {
foreach (var property in this.propItems) {
image.SetPropertyItem(property);
}
image.Save(@"D:\Temp\1.jpg");
}
不再使用FileStream了。请注意,保存图像的文件不能与您从中读取图像的文件相同。有人暗示你试图解决这个问题。使用MemoryStream是避免锁定文件的常用技术。
另请注意代码中的另一个错误,您使用.jpg扩展程序保存文件,但它实际上是PNG。如果需要JPEG,则不能省略ImageFormat参数。