3

我需要在不修改图像内容的情况下将唯一 ID 插入到图像文件中——即它只是我想要修改的元数据。我从 JPEG 文件开始,因为有一个适当的 EXIF 属性可用:ImageUniqueID

我将 C# 与 .NET Core 3.1 一起用于ImageSharp的这个练习。我可以使用以下代码使用 ImageSharp 更改 EXIF 数据(在没有现有记录检查的情况下显示简化等):

using (var image = Image.Load(filename))
            {
            var imageUniqueIdentifier = Guid.NewGuid().ToString().ToLower().Replace("-", "");
            image.Metadata.ExifProfile.SetValue(ExifTag.ImageUniqueID, imageUniqueIdentifier);

            var jpegEncoder = new JpegEncoder() { Quality = 100 };
            image.Save(filename, jpegEncoder);
            }

我确实使用了 JpegEncoder 中的质量设置,但仍然出现不可接受的质量下降或文件大小增加。

有没有一种方法可以只读取元数据,对其进行更改然后将其写回而不影响图像?

我还查看了MetadataExtractor.NET,但它没有写入工具,我很乐意查看其他 .NET Core 方法或库。

4

2 回答 2

5

经过一些研究,我发现有ExifLibrary允许您仅修改图像元数据。 文档(包括示例)

示例如何为 jpg 文件添加唯一图像 ID:

var file = ImageFile.FromFile("path_to_jpg_file");
var imageUniqueIdentifier = Guid.NewGuid().ToString().ToLower().Replace("-", "");
file.Properties.Set(ExifLibrary.ExifTag.ImageUniqueID, imageUniqueIdentifier);

file.Save("path_to_jpg_file");

Nuget 包:ExifLibNet。

于 2021-01-12T15:21:41.180 回答
2

这是一些只需要 .NET 和 PresentationCore 和 WindowsBase 的代码。WPF 使用的底层技术是 WIC(Windows 映像组件)。WIC 完全支持图像元数据

EXIF 的ImageUniqueID专门作为名为System.Image.ImageID的 Windows 属性处理

如果您添加相应的列“相机型号”,则可以在 Windows 资源管理器详细视图中直接看到 System.Photo.CameraModel 等其他一些属性,而不是 System.Image.ImageID,AFAIK。

// needs PresentationCore & WindowsBase references
var frame = BitmapDecoder.Create(new Uri("test1.jpg", UriKind.RelativeOrAbsolute), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None).Frames[0];

// create encoder, add frame, we need to copy since we want to update metadata
var encoder = BitmapEncoder.Create(frame.Decoder.CodecInfo.ContainerFormat);
var copy = BitmapFrame.Create(frame);

// get frame metadata
var metaData = (BitmapMetadata)copy.Metadata;

// show existing System.Image.ImageID (if any)
Console.WriteLine("ImageUniqueID: " + metaData.GetQuery("System.Image.ImageID"));

// for some reason, we can't use "System.Image.ImageID" to set the meta data
// so use the "Metadata Query Language"
metaData.SetQuery("/app1/ifd/exif/{ushort=42016}", "My Super ID");

// write file back
encoder.Frames.Add(copy);
using (var stream = File.OpenWrite("test1copy.jpg"))
{
    encoder.Save(stream);
}
于 2021-01-15T19:03:16.313 回答