当我将Exif元数据从一个文件复制到另一个文件时,如果源文件的EXIF缩略图的长度为65173字节,并添加一些新的EXIF元数据字段,则JPEGBitMapEncoder保存操作
destinationEncoder.Save(destinationStream);
出现消息“提交失败,因为元数据更改太多”失败。如果Exif缩略图的长度较短(大约7000个字节),则复制后添加元数据和添加元数据即可。
如果我尝试通过取消注释该行来删除EXIF缩略图
//sourceMetadata.RemoveQuery("/app1/ifd/exif:{uint=20507}"); // remove thumbnail data
我仍然收到“提交失败”消息。
如何在不收到此错误消息的情况下添加EXIF元数据字段?
public void CopyMetadata(string sourceFile, string destinationFile, string sXPTitle, string sXPSubject,
string sXPComment, bool bAspectRatioNotSet, int Width, int Height, bool bShowErrors = false)
{
string tempFile = destinationFile + ".tmp3";
uint paddingAmount = 2048;
// from http://www.dustyfish.com/blog/copying-jpeg-metadata-using-c-and-windows-imaging-component
//BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile; // Create backup of the file so you can read and write to different files
BitmapCreateOptions createOptions = new BitmapCreateOptions();
System.IO.File.Copy(destinationFile, tempFile, true); // Open the source file
//System.IO.File.Copy(sourceFile, tempFile, true); // Open the source file
using (Stream sourceStream = System.IO.File.Open(sourceFile, FileMode.Open, FileAccess.Read))
{
BitmapDecoder sourceDecoder = BitmapDecoder.Create(sourceStream, createOptions, BitmapCacheOption.None); // Check source is has valid frames
if (sourceDecoder.Frames[0] != null && sourceDecoder.Frames[0].Metadata != null)
{
// Get a clone copy of the metadata
BitmapMetadata sourceMetadata = sourceDecoder.Frames[0].Metadata.Clone() as BitmapMetadata;
// modify values
sourceMetadata.SetQuery("/app1/ifd/PaddingSchema:Padding", paddingAmount);
sourceMetadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", paddingAmount);
sourceMetadata.SetQuery("/xmp/PaddingSchema:Padding", paddingAmount);
sourceMetadata.SetQuery("/app1/ifd/exif:{uint=256}", Width);
sourceMetadata.SetQuery("/app1/ifd/exif:{uint=257}", Height);
Encoding _Encoding = Encoding.UTF8;
sourceMetadata.SetQuery("/app1/ifd/exif:{uint=40091}", _Encoding.GetBytes(sXPTitle + '\0'));// uint=40091
sourceMetadata.SetQuery("/app13/irb/8bimiptc/iptc/object name", sXPTitle);
sourceMetadata.SetQuery("/xmp/Description:Description", (sXPTitle + " " + sXPSubject).Replace(Environment.NewLine, " ").ToCharArray());// XMP Description
sourceMetadata.SetQuery("/app1/ifd/exif:{uint=40095}", _Encoding.GetBytes(sXPSubject + '\0')); // uint 40095
sourceMetadata.SetQuery("/app13/irb/8bimiptc/iptc/Caption", sXPSubject.Replace(Environment.NewLine, " "));
sourceMetadata.SetQuery("/xmp/Description:Description", (sXPTitle + " " + sXPSubject).Replace(Environment.NewLine, " ").ToCharArray());// XMP Description
sourceMetadata.SetQuery("/app1/ifd/exif:{uint=40092}", _Encoding.GetBytes(sXPComment + '\0')); // uint 40092
if (!bAspectRatioNotSet)
sourceMetadata.SetQuery("/app1/ifd/exif:{uint=274}", (ushort)1);
//sourceMetadata.RemoveQuery("/app1/ifd/exif:{uint=20507}"); // remove thumbnail data)
using (Stream tempStream = System.IO.File.Open(tempFile, FileMode.Open, FileAccess.Read))
{
BitmapDecoder tempDecoder = BitmapDecoder.Create(tempStream, createOptions, BitmapCacheOption.None); // Check temp file has valid frames
if (tempDecoder.Frames[0] != null && tempDecoder.Frames[0].Metadata != null)
{
// Open the destination file
using (Stream destinationStream = System.IO.File.Open(destinationFile, FileMode.Open, FileAccess.ReadWrite))
{
// Create a new jpeg frame, replacing the destination metadata with the source
BitmapFrame destinationFrame = BitmapFrame.Create(tempDecoder.Frames[0],
tempDecoder.Frames[0].Thumbnail,
sourceMetadata,
tempDecoder.Frames[0].ColorContexts); // Save the file
JpegBitmapEncoder destinationEncoder = new JpegBitmapEncoder();
destinationEncoder.Frames.Add(destinationFrame);
destinationEncoder.Save(destinationStream);
}
}
}
}
}
}