【问题标题】:Reading metadata from images in WPF从 WPF 中的图像中读取元数据
【发布时间】:2009-03-27 08:58:42
【问题描述】:

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

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

【问题讨论】:

    标签: .net wpf image metadata


    【解决方案1】:

    查看我的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;
                }
            }
        }
    }
    

    【讨论】:

    • 谢谢!奇怪的是 BitmapMetadata 没有像 DateTaken、Author 等那样包含 Orientation 属性。
    • 对于通过谷歌来到这里的其他人,上面肯特示例中的_orientationQuery 是"System.Photo.Orientation"
    • Kent,你为什么只处理三个值?根据这篇文章,您还应该处理镜像值(2、4、5 和 7)。 daveperrett.com/articles/2012/07/28/…
    • @Charlie:只是无知-我不知道镜像值。也就是说,我不完全确定我理解何时或为什么会“从里到外”拍摄照片,以及镜像值如何有用。
    • 在我自己的照片库中对此进行了测试后,仅处理这 3 个值似乎就足以捕获所有旋转不当的值。我想我没有任何“镜像”图像。 ://
    【解决方案2】:

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

    我维护一个simple open-source library 用于从图像和视频中提取元数据。它是 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() });
    

    metadata-extractor 库可通过NuGet 和code's on GitHub 获得。

    感谢自 2002 年项目启动以来帮助该项目的许多贡献者。

    【讨论】:

    • 不应该是ExifDirectoryBase.TagOrientation吗?
    猜你喜欢
    • 1970-01-01
    • 2022-12-21
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多