5

我知道 WPF 允许您使用需要 WIC 编解码器才能查看的图像(为了争论,比如说数码相机 RAW 文件);但是我只能看到它可以让您以本机方式显示图像,但无论如何我都看不到获取元数据(例如,曝光时间)。

正如 Windows 资源管理器显示的那样,这显然可以完成,但是这是通过 .net API 公开的,还是您认为它只是调用本机 COM 接口

4

2 回答 2

13

查看我的Intuipic项目。特别是BitmapOrientationConverter类,它读取元数据以确定图像的方向:

private const string _orientationQuery = "System.Photo.Orientation";
...

using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
    BitmapFrame bitmapFrame = BitmapFrame.Create(fileStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
    BitmapMetadata bitmapMetadata = bitmapFrame.Metadata as BitmapMetadata;

    if ((bitmapMetadata != null) && (bitmapMetadata.ContainsQuery(_orientationQuery)))
    {
        object o = bitmapMetadata.GetQuery(_orientationQuery);

        if (o != null)
        {
            //refer to http://www.impulseadventure.com/photo/exif-orientation.html for details on orientation values
            switch ((ushort) o)
            {
                case 6:
                    return 90D;
                case 3:
                    return 180D;
                case 8:
                    return 270D;
            }
        }
    }
}
于 2009-03-27T09:14:48.433 回答
4

虽然 WPF 确实提供了这些 API,但它们不是很友好,也不是特别快。我怀疑他们正在做很多互操作。

我维护一个简单的开源库,用于从图像和视频中提取元数据。它是 100% C#,没有 P/Invoke。

// Read all metadata from the image
var directories = ImageMetadataReader.ReadMetadata(stream);

// Find the so-called Exif "SubIFD" (which may be null)
var subIfdDirectory = directories.OfType<ExifSubIfdDirectory>().FirstOrDefault();

// Read the orientation
var orientation = subIfdDirectory?.GetInt(ExifDirectoryBase.TagOrientation);

switch (orientation)
{
    case 6:
        return 90D;
    case 3:
        return 180D;
    case 8:
        return 270D;
}

在我的基准测试中,这比 WPF API 快 17 倍。如果您只想要 JPEG 中的 Exif,请使用以下命令,它的速度会快 30 倍以上:

var directories = JpegMetadataReader.ReadMetadata(stream, new[] { new ExifReader() });

数据提取器库可通过NuGet获得,代码位于 GitHub 上

这要归功于自 2002 年项目启动以来帮助该项目的许多贡献者。

于 2016-10-03T21:13:19.843 回答