You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何向JPEG文件写入字符串类型EXIF元数据?

解决EXIF字符串类型元数据(如拍摄时间)写入问题

你遇到的问题核心在于EXIF字符串字段有严格的格式和编码要求,尤其是像拍摄时间这类日期时间字段,必须完全符合EXIF规范才能成功写入,而非简单传递任意字符串。以下是具体解决步骤和代码示例:

关键注意事项

  • EXIF日期时间格式:必须严格遵循 yyyy:MM:dd HH:mm:ss 格式,分隔符用冒号(不能用斜杠或其他符号),例如 2024:05:20 14:30:00。
  • 正确的查询路径:不同EXIF字符串字段对应不同查询路径,比如拍摄时间(DateTimeOriginal)的路径是 /app1/{ushort=0}/{ushort=36867}(标签值0x9003)。
  • 编码要求:EXIF字符串字段默认使用ASCII编码,避免包含非ASCII字符,否则可能写入失败。

完整读写示例(拍摄时间)

读取拍摄时间

string imagePath = @"C:\Users\xxxx\Desktop\xxxx.JPG";
string dateQuery = "/app1/{ushort=0}/{ushort=36867}"; // DateTimeOriginal标签

// 读取逻辑
using (FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
{
    BitmapFrame bitmapFrame = BitmapFrame.Create(stream);
    BitmapMetadata metadata = (BitmapMetadata)bitmapFrame.Metadata;

    if (metadata.ContainsQuery(dateQuery))
    {
        string originalDate = metadata.GetQuery(dateQuery) as string;
        Console.WriteLine($"原拍摄时间:{originalDate}");
    }
}

写入新的拍摄时间

string newDate = "2024:05:20 14:30:00"; // 严格符合EXIF格式

using (FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
    BitmapFrame bitmapFrame = BitmapFrame.Create(stream);
    InPlaceBitmapMetadataWriter metadataWriter = bitmapFrame.CreateInPlaceBitmapMetadataWriter();

    // 先确认支持原地写入
    if (!metadataWriter.TrySave())
    {
        throw new IOException("图片不支持原地修改元数据");
    }

    // 设置新的拍摄时间
    metadataWriter.SetQuery(dateQuery, newDate);

    if (!metadataWriter.TrySave())
    {
        throw new IOException("写入拍摄时间失败");
    }
}

常见问题排查

  1. 写入失败但无报错:检查字符串格式是否完全符合yyyy:MM:dd HH:mm:ss,比如是否用了斜杠代替冒号,或者日期时间值非法(如月份超过12)。
  2. 仅能写入短字符串:大概率是编码或格式问题,确保字符串是纯ASCII字符,且符合对应EXIF字段的格式要求(比如作者字段可使用任意ASCII字符串,但日期时间必须严格遵循格式)。
  3. 原地写入失败:部分图片(如经过编辑压缩的JPEG)可能不支持原地修改元数据,此时需要将图片复制到新流中,写入元数据后保存为新文件:
// 非原地写入示例
using (FileStream inputStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
using (FileStream outputStream = new FileStream(imagePath + "_new.jpg", FileMode.Create, FileAccess.Write))
{
    BitmapFrame bitmapFrame = BitmapFrame.Create(inputStream);
    BitmapMetadata metadata = (BitmapMetadata)bitmapFrame.Metadata.Clone();
    metadata.SetQuery(dateQuery, newDate);

    BitmapEncoder encoder = new JpegBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metadata, bitmapFrame.ColorContexts));
    encoder.Save(outputStream);
}

内容的提问来源于stack exchange,提问作者Daniel Müller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:54:38