0

我正在尝试使用 System.​Windows.​Media.​Imaging 将 Exif 数据添加到图像中。我能找到的大多数示例代码都适用于 JPG,但不适用于 Tiff。显然,代码无法扩展标题以添加新的 Exif 字段。下面的代码中缺少的任何想法。输出的 JPG 将在 Exif 中具有“焦距”和“纬度”值。但输出 TIF 不会。

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Media.Imaging;

namespace TestExifCs
{
    class Program
    {

#define DO_TIFF
        static void RunSample(string originalPath)
        {

            BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;

            uint paddingAmount = 2048; 

            using (Stream originalFile = File.Open(originalPath, FileMode.Open, FileAccess.Read))
            {
                BitmapDecoder original = BitmapDecoder.Create(originalFile, createOptions, BitmapCacheOption.None);
                // Pick the appropriate decoder.
#ifdef DO_TIFF
                string outputPath = @"C:\temp\out.tif";
                TiffBitmapEncoder output = new TiffBitmapEncoder();
#else
                string outputPath = @"C:\temp\out.jpg";
                JpegBitmapEncoder output = new JpegBitmapEncoder();
#endif

                if (original.Frames[0] != null && original.Frames[0].Metadata != null)
                {                       
                    BitmapMetadata metadata = original.Frames[0].Metadata.Clone() as BitmapMetadata;
                    // Expand the image file directory for new items.
                    metadata.SetQuery("/app1/ifd/PaddingSchema:Padding", paddingAmount);
                    metadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", paddingAmount);

                    // Add focal length
                    byte[] f = new byte[8] { 0x70, 0x03, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00 };
                    metadata.SetQuery("/app1/ifd/exif/{uint=37386}", f);

                    // Add latitude
                    byte[] bArray = new byte[0x18] { 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x42, 0xd7, 0x04, 0x00, 0x10, 0x27, 0x00, 0x00 };
                    metadata.SetQuery("/app1/ifd/gps/subifd:{ulong=2}", bArray);

                    // Create a new frame identical to the one from the original image, except for the added metadata
                    output.Frames.Add(BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, metadata, original.Frames[0].ColorContexts));
                }

                using (Stream outputFile = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
                {
                    output.Save(outputFile);
                }
            }
        }

        static void Main(string[] args)
        {
            RunSample("C:\\temp\\test.tif");
        }
    }
}
4

1 回答 1

0

我遇到了同样的问题,但我试图用 System.Drawing.Image.SetPropertyItem() 设置 EXIF 标记。在我看来,C# 系统库只是不支持在 TIFF 中像在 JPEG 中那样操作 EXIF 标记。

TIFF 格式在称为图像文件目录 (IFD) 的表中支持其自己的一组标记。IFD 中的每个条目都有一个 2 字节的“标签”来定义条目是什么。我可以使用 C# 库编辑此表中的大多数条目:我可以使用由 TIFF 格式定义的“标签”读取/写入条目(例如 ImageWidth=0x100),并且可以读取/写入带有任意“私有”标签的条目我自己编。

在 TIFF 中通过使用“Type”=“Exif IFD”=0x8769”的私有 IFD 条目来支持 EXIF,其中包含对包含所有 EXIF 特定标签的新 IFD 的偏移量。虽然我可以读取其他私有 TIFF 标签,我无法使用 GetPropertyItem() 检索“Exif IFD”条目。我注意到有一些 TIFF 标签是不允许我读取的,它们都是包含到另一个 IFD 的偏移量的那种。

能够使用EXIF IFD 标签编写TIFF IFD 条目。幸运的是,我试图编写 TIFF 标签,而不是阅读它们,所以我通过手工解决了缺乏支持的问题;创建一个简单的 EXIF IFD,将其附加到我的文件末尾,然后编辑 TIFF EXIF IFD 条目以指向它。然后,Windows 资源管理器能够从我的 TIFF 中读取 EXIF。

于 2017-09-05T13:34:02.060 回答