Reading metadata from images in WPF

后端 未结 2 1390
忘掉有多难
忘掉有多难 2020-12-10 19:52

I\'m aware that WPF allows you to use images that require WIC codecs to view (for the sake of argument, say a digital camera RAW file); however I can only see that it lets y

相关标签:
2条回答
  • 2020-12-10 20:36

    Check out my Intuipic project. In particular, the BitmapOrientationConverter class, which reads metadata to determine the image's orientation:

    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;
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-10 20:37

    Whilst WPF does provide these APIs, they're not very friendly and they're not particularly fast. I suspect they're doing a lot of interop.

    I maintain a simple open-source library for extracting metadata from images and videos. It's 100% C# with no 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;
    }
    

    In my benchmarks, this is 17 times faster than the WPF API. If you only want Exif from JPEG, use the following and it's over 30 times faster:

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

    The metadata-extractor library is available via NuGet and the code's on GitHub.

    Credit is due to the many contributors who've helped the project since it started in 2002.

    0 讨论(0)
提交回复
热议问题