Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: Rowland ShawОтветов: 2

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

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

imagemetadatawpf

Ответы

Ответ 1 · рейтинг 12 · Kent Boogaart

Посмотрите мой проект 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;
            }
        }
    }
}

Ответ 2 · рейтинг 4 · Drew Noakes

Хотя 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 и на GitHub.

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы