C# JpegBitmapEncoder.Save()在使用元数据写入图像时引发异常
我正在构建一个WPF桌面应用程序,帮助我整理照片并发布到Facebook。以下是我在新位置创建照片副本的代码,添加了标题(EXIF+IPTC+XMP): 运行该命令后,我得到一个“COMException was unhandled”异常,突出显示这一行:C# JpegBitmapEncoder.Save()在使用元数据写入图像时引发异常,c#,wpf,metadata,exif,iptc,C#,Wpf,Metadata,Exif,Iptc,我正在构建一个WPF桌面应用程序,帮助我整理照片并发布到Facebook。以下是我在新位置创建照片副本的代码,添加了标题(EXIF+IPTC+XMP): 运行该命令后,我得到一个“COMException was unhandled”异常,突出显示这一行: encoder.Save(memstream); 中发生类型为“System.Runtime.InteropServices.COMException”的未处理异常 PresentationCore.dll 附加信息:句柄无效。(HRESU
encoder.Save(memstream);
中发生类型为“System.Runtime.InteropServices.COMException”的未处理异常
PresentationCore.dll
附加信息:句柄无效。(HRESULT的异常:0x80070006(E_句柄))
我发现这可能是由于线程问题,因此我没有直接从应用程序调用SaveImageAs,而是添加了以下内容,但没有任何效果:
private void _SaveImageAs(string currPath, string newPath, bool setCaption = false, string captionToSet = "")
{
Thread saveThread = new Thread(() => SaveImageAs(currPath, newPath, setCaption, captionToSet));
saveThread.SetApartmentState(ApartmentState.STA);
saveThread.IsBackground = false;
saveThread.Start();
}
我还尝试将MemoryStream换成FileStream,创建一个本地临时文件,但没有改变任何东西:
FileStream memstream = new FileStream(System.IO.Path.GetDirectoryName(newPath) + @"\" + "temp.jpg", System.IO.FileMode.OpenOrCreate);
有什么想法吗?您得到了异常,因为您关闭了用于加载原始jpeg的流。注释第一个stream.Close()(就在if(setCaption)的上方),它就可以工作了。就像处理映像实例一样,您必须在映像的生命周期内保持流的打开状态。代码中有一些错误
public static void SaveImageAs(string sourcePath, string targetPath, string caption)
{
using (var sourceStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var decoder = new JpegBitmapDecoder(sourceStream, BitmapCreateOptions.None, BitmapCacheOption.None);
var frame = decoder.Frames[0];
if (!string.IsNullOrWhiteSpace(caption))
{
frame = BitmapFrame.Create(frame);
var metadata = (BitmapMetadata)frame.Metadata;
metadata.SetQuery("/app1/ifd/{uint=270}", caption);
metadata.SetQuery("/app13/irb/8bimiptc/iptc/Caption", caption);
//metadata.SetQuery("/xmp/dc:description/x-default", caption);
}
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(frame);
using (var targetStream = new FileStream(targetPath, FileMode.Create))
{
encoder.Save(targetStream);
}
}
}
使用BitmapCacheOption.OnLoad而不是None会使代码运行速度慢10倍以上(在100个图像上测试,每个图像大约1M)。
public static void SaveImageAs(string sourcePath, string targetPath, string caption)
{
using (var sourceStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var decoder = new JpegBitmapDecoder(sourceStream, BitmapCreateOptions.None, BitmapCacheOption.None);
var frame = decoder.Frames[0];
if (!string.IsNullOrWhiteSpace(caption))
{
frame = BitmapFrame.Create(frame);
var metadata = (BitmapMetadata)frame.Metadata;
metadata.SetQuery("/app1/ifd/{uint=270}", caption);
metadata.SetQuery("/app13/irb/8bimiptc/iptc/Caption", caption);
//metadata.SetQuery("/xmp/dc:description/x-default", caption);
}
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(frame);
using (var targetStream = new FileStream(targetPath, FileMode.Create))
{
encoder.Save(targetStream);
}
}
}