我有 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 was unhandled
HResult=-2147467259 Message=A generic error occurred in GDI+.
Source=System.Drawing ErrorCode=-2147467259
我的第二段代码运行良好,我可以获得正确的输出。这里有什么区别?
最佳答案
这是设计使然,MSDN 的 Image.FromStream() 文章对此提出了严厉警告。一旦关闭流,图像就不再可用。尝试像您一样保存它很可能(但不能保证)在尝试从关闭的流中检索像素数据时抛出异常。
Image 类的一个关键属性是它是惰性的,与许多 .NET 类不同,它在必要时不会访问流数据。在实际使用像素数据之前,这是没有必要的,这发生在代码片段中的 Save() 调用中。当它无法再读取时,会出现 Kaboom。
您可以通过将 Save() 调用移至 using 语句内来修复第一个代码片段:
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 参数。
关于c# - 从流中打开的图像与从文件中打开的图像不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22084813/