用于无损 Exif 重写的 .NET C# 库?

发布于 2024-07-25 13:11:35 字数 1542 浏览 11 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

っ左 2024-08-01 13:11:35

如果您计划编写自己的库来编辑标签,则以下是 Exif 交换格式的规范。

http://www.exif.org/specifications.html

这是一个用 Perl 编写的库,满足您可以从中了解您的需求:

http://www.sno。 phy.queensu.ca/~phil/exiftool/

这是一个不错的 .NET 库,用于 Exif 评估,来自 代码项目

http://www.codeproject.com/KB/graphics /exiftagcol.aspx

Here are the specifications for the Exif interchange format, if you plan to code your own library for editing tags.

http://www.exif.org/specifications.html

Here's a library written in Perl that meets your needs that you may be able to learn from:

http://www.sno.phy.queensu.ca/~phil/exiftool/

Here's a decent .NET library for Exif evaluation from The Code Project:

http://www.codeproject.com/KB/graphics/exiftagcol.aspx

孤君无依 2024-08-01 13:11:35

您可以在没有任何外部库的情况下执行此操作:

// Create image.
Image image1 = Image.FromFile("c:\\Photo1.jpg");

// Get a PropertyItem from image1. Because PropertyItem does not
// have public constructor, you first need to get existing PropertyItem
PropertyItem propItem = image1.GetPropertyItem(20624);

// Change the ID of the PropertyItem.
propItem.Id = 20625;

// Set the new PropertyItem for image1.
image1.SetPropertyItem(propItem);

// Save the image.
image1.Save("c:\\Photo1.jpg", ImageFormat.Jpg);

您可以找到的所有可能的 PropertyItem id(包括 exif)的列表 此处

更新:同意,此方法将在保存时重新编码图像。 但我想起了另一种方法,在WinXP SP2及更高版本中添加了新的成像组件-WIC,你可以使用它们无损写入元数据-操作方法:使用元数据重新编码 JPEG 图像

You can do this without any external lib:

// Create image.
Image image1 = Image.FromFile("c:\\Photo1.jpg");

// Get a PropertyItem from image1. Because PropertyItem does not
// have public constructor, you first need to get existing PropertyItem
PropertyItem propItem = image1.GetPropertyItem(20624);

// Change the ID of the PropertyItem.
propItem.Id = 20625;

// Set the new PropertyItem for image1.
image1.SetPropertyItem(propItem);

// Save the image.
image1.Save("c:\\Photo1.jpg", ImageFormat.Jpg);

List of all possible PropertyItem ids (including exif) you can found here.

Update: Agreed, this method will re-encode image on save. But I have remembered another method, in WinXP SP2 and later there is new imaging components added - WIC, and you can use them to lossless write metadate - How-to: Re-encode a JPEG Image with Metadata.

沉鱼一梦 2024-08-01 13:11:35

exiv2net 库(exiv2 之上的 .NET 包装器)可能就是您想要的为了。

exiv2net library (a .NET wrapper on top of exiv2) may be what you're looking for.

2024-08-01 13:11:35

我写了一个小测试,我多次压缩一个文件来查看质量下降情况,你可以在第三次第四次压缩中看到它,这是非常糟糕的。

但幸运的是,如果您始终对 JpegBitmapEncoder 使用相同的 QualityLevel,则不会出现降级。

在此示例中,我在元数据中重写了 100 倍的关键字,但质量似乎没有改变。

private void LosslessJpegTest() {
  var original = "d:\\!test\\TestInTest\\20150205_123011.jpg";
  var copy = original;
  const BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;

  for (int i = 0; i < 100; i++) {
    using (Stream originalFileStream = File.Open(copy, FileMode.Open, FileAccess.Read)) {
      BitmapDecoder decoder = BitmapDecoder.Create(originalFileStream, createOptions, BitmapCacheOption.None);

      if (decoder.CodecInfo == null || !decoder.CodecInfo.FileExtensions.Contains("jpg") || decoder.Frames[0] == null)
        continue;

      BitmapMetadata metadata = decoder.Frames[0].Metadata == null
        ? new BitmapMetadata("jpg")
        : decoder.Frames[0].Metadata.Clone() as BitmapMetadata;

      if (metadata == null) continue;

      var keywords = metadata.Keywords == null ? new List<string>() : new List<string>(metadata.Keywords);
      keywords.Add($"Keyword {i:000}");
      metadata.Keywords = new ReadOnlyCollection<string>(keywords);

      JpegBitmapEncoder encoder = new JpegBitmapEncoder {QualityLevel = 80};
      encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0], decoder.Frames[0].Thumbnail, metadata,
        decoder.Frames[0].ColorContexts));

      copy = original.Replace(".", $"_{i:000}.");

      using (Stream newFileStream = File.Open(copy, FileMode.Create, FileAccess.ReadWrite)) {
        encoder.Save(newFileStream);
      }
    }
  }
}

I wrote a small test where I compress one file many times to see the quality degradation and you can see it in the third-fourth compression, which is very bad.

But luckily, if you always use same QualityLevel with JpegBitmapEncoder there is no degradation.

In this example I rewrite keywords 100x in metadata and the quality seems not to change.

private void LosslessJpegTest() {
  var original = "d:\\!test\\TestInTest\\20150205_123011.jpg";
  var copy = original;
  const BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;

  for (int i = 0; i < 100; i++) {
    using (Stream originalFileStream = File.Open(copy, FileMode.Open, FileAccess.Read)) {
      BitmapDecoder decoder = BitmapDecoder.Create(originalFileStream, createOptions, BitmapCacheOption.None);

      if (decoder.CodecInfo == null || !decoder.CodecInfo.FileExtensions.Contains("jpg") || decoder.Frames[0] == null)
        continue;

      BitmapMetadata metadata = decoder.Frames[0].Metadata == null
        ? new BitmapMetadata("jpg")
        : decoder.Frames[0].Metadata.Clone() as BitmapMetadata;

      if (metadata == null) continue;

      var keywords = metadata.Keywords == null ? new List<string>() : new List<string>(metadata.Keywords);
      keywords.Add($"Keyword {i:000}");
      metadata.Keywords = new ReadOnlyCollection<string>(keywords);

      JpegBitmapEncoder encoder = new JpegBitmapEncoder {QualityLevel = 80};
      encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0], decoder.Frames[0].Thumbnail, metadata,
        decoder.Frames[0].ColorContexts));

      copy = original.Replace(".", $"_{i:000}.");

      using (Stream newFileStream = File.Open(copy, FileMode.Create, FileAccess.ReadWrite)) {
        encoder.Save(newFileStream);
      }
    }
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文