C# 将标记值添加到图像中的现有exif配置文件

C# 将标记值添加到图像中的现有exif配置文件,c#,imagemagick,exif,magick.net,C#,Imagemagick,Exif,Magick.net,我使用库读取exif值。为了获得最高性能,我使用了Ping方法(请参阅),因为在处理某些图像元数据时,我不需要实际的图像内容 但现在,如果这个值不存在,我需要写入exif标记值。我想做的是: public static void Test() { var path = @"C:\image.jpg"; using (var image = new MagickImage()) { image.Ping(pa

我使用库读取exif值。为了获得最高性能,我使用了
Ping
方法(请参阅),因为在处理某些图像元数据时,我不需要实际的图像内容

但现在,如果这个值不存在,我需要写入exif标记值。我想做的是:

    public static void Test()
    {
        var path = @"C:\image.jpg";

        using (var image = new MagickImage())
        {
            image.Ping(path);

            var profile = image.GetExifProfile();

            var copyright = profile.Values.FirstOrDefault(x => x.Tag == ExifTag.Copyright);
            if (copyright != null)
            {
                Trace.WriteLine("Copyright: " + copyright);
            }
            else
            {
                Trace.WriteLine("Write Copyright data");

                profile.SetValue(ExifTag.Copyright, "Example text");
                image.AddProfile(profile, true);
                image.Write(path);
            }
        }
    }
但此代码不是将标记值写入exif。以另一种方式打开文件时,我可以成功写入标记值(如下所示):

但这种方法可以解码整个图像内容,我不需要它来改变“内容独立”标签的值,比如版权或日期时间

问题是:如何编辑这个exif标签,而不加载整个图像内容?

我是否需要重写整个exif配置文件(
image.AddProfile(profile,true)
),还是有办法编辑配置文件?

不幸的是,在Magick.NET中无法做到这一点。您需要使用
读取图像的所有像素。如果要写入图像,请读取
。仅当您希望从图像中获取信息而不加载整个图像时,才应使用
.Ping
方法

无法仅替换/编辑一个值。您正在正确地替换配置文件。但是您不需要
true
,因为这是AddProfile的默认值

可能还有另一个图书馆可以帮你解决这个问题。您还可以阅读JPEG规范,并在文件中找到EXIF配置文件的位置。然后使用ExifProfile类修改它并将其写回映像。我将把这部分留给读者作为练习


这个特性也不太可能最终出现在ImageMagick中,因为这意味着我们必须重写编码和解码图像的方式。作为Magick.NET的维护者,我可以在将来添加这个额外的功能。我已经编写了ImageOptimizers,可以用来减小不属于ImageMagick的JPG/PNG图像的大小。但是我不能告诉你什么时候可以使用。

我怀疑有类似的情况,但感谢你确认信息。在获得JPEG规范信息后,我得出结论,使用特定的,支持良好的工具,而不是手动干预jpeg,可能会产生意想不到的后果:)最后一个问题:如果技术上可行-有一天我们会在Magick.NET中看到类似“exif edit with content loading”(无内容加载的exif edit)的功能的可能性有多大?这个功能似乎不像我想的那么简单,因此,我们将找到一些其他方法来暂时增强exif编辑。但我们很高兴在将来看到这个功能:)无论如何,谢谢你的回答和Magick.NET!
        var path = @"C:\image.jpg";

        // Read image with content
        using (var image = new MagickImage(path))
        {
            // image.Ping(path) - no more need
            var profile = image.GetExifProfile();

            ...
        }