Чтение метаданных из изображений в WPF

Я знаю, что WPF позволяет вам использовать изображения, для просмотра которых требуются кодеки WIC (ради аргумента, скажем, файл RAW цифровой камеры); однако я вижу только то, что он позволяет отображать изображение изначально, но я не вижу возможности получить метаданные (например, время экспозиции).

Это, очевидно, можно сделать, как показывает проводник Windows, но это доступно через .net API или вы считаете, что это просто вызов собственных COM-интерфейсов.


person Rowland Shaw    schedule 27.03.2009    source источник


Ответы (2)


Посмотрите мой проект 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;
            }
        }
    }
}
person Kent Boogaart    schedule 27.03.2009
comment
Спасибо за это! Странно, что BitmapMetadata не содержит свойство Orientation, как для DateTaken, Author и т. д. - person Isak Savo; 14.07.2011
comment
Для других людей, которые приходят сюда через Google, _orientationQuery в приведенном выше примере Кента будет "System.Photo.Orientation". - person Isak Savo; 28.07.2011
comment
Кент, по какой причине вы обрабатываете только три значения? Согласно этой статье, вы также должны обрабатывать зеркальные значения (2, 4, 5 и 7). daveperrett.com/articles/2012 /28/07/ - person Charlie; 21.11.2013
comment
@Charlie: просто невежество - я не знал о значениях зеркального отображения. Тем не менее, я не совсем уверен, что понимаю, когда и почему может произойти съемка фотографии наизнанку, и, следовательно, как полезны значения зеркального отображения. - person Kent Boogaart; 21.11.2013
comment
После тестирования этого в моей собственной библиотеке фотографий, кажется, что просто обработки этих трех значений достаточно, чтобы поймать все неправильно повернутые. Я думаю, что у меня нет никаких зеркальных изображений. :/ - person Charlie; 21.11.2013
comment
Ну, вы все равно не можете просто вернуть угол для этих случаев. - person Nyerguds; 27.09.2019

Хотя 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;
}

В моих тестах это в 17 раз быстрее, чем WPF API. Если вам нужен только Exif из JPEG, используйте следующее, и это более чем в 30 раз быстрее:

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

Библиотека metadata-extractor доступна через NuGet и < код href="https://github.com/drewnoakes/metadata-extractor-dotnet" rel="nofollow noreferrer">на GitHub.

Это заслуга многих участников, которые помогали проекту с момента его запуска в 2002 году.

person Drew Noakes    schedule 03.10.2016
comment
Разве это не должно быть ExifDirectoryBase.TagOrientation? - person Wouter; 06.07.2018