在WPF中读取图像元数据

5
我知道WPF允许您使用需要WIC编解码器才能查看的图像(例如数码相机RAW文件)。但是,我只能看到它可以原生地显示图像,但我无法找到任何获取元数据的方法(例如曝光时间)。
显然可以做到,因为Windows资源管理器可以显示它,但是它是通过.NET API公开还是只需调用本机COM接口?
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;
            }
        }
    }
}

1
谢谢!很奇怪BitmapMetadata不像DateTaken、Author等那样包含“方向”属性。 - Isak Savo
4
对于通过谷歌搜索到这里的其他人,肯特上面示例中的_orientationQuery"System.Photo.Orientation" - Isak Savo
肯特,你只处理三个值的原因是什么?根据这篇文章,你应该也要处理镜像的值(2、4、5和7)。http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/ - Charlie
@Charlie:只是无知——我不知道镜像值的存在。话虽如此,我并不完全明白为什么或何时会出现“内外颠倒”的拍照情况,因此也不确定镜像值有什么用处。 - Kent Boogaart
在我的照片库上测试后,仅处理这3个值似乎足以捕捉所有不正确旋转的图像。我想我没有任何“镜像”图像。 :/ - Charlie
好的,无论如何你都不能返回一个角度来处理这些情况。 - Nyerguds

4
尽管WPF提供了这些API,但它们不太友好,也不是特别快。我怀疑它们在做很多交互操作。
我维护一个用于从图像和视频中提取元数据的简单开源库。它完全使用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() });

"

metadata-extractor 库可以通过 NuGetGitHub 上的代码 获得。

自从 2002 年启动以来,许多贡献者对该项目做出了贡献,特此致谢。

"

那不应该是 ExifDirectoryBase.TagOrientation 吗? - Wouter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接