Як отримати дані EXIF ​​з файлу за допомогою C #


77

Я хотів би написати невелику програму на C #, яка переглядає мої фотографії jpeg і, наприклад, сортує їх у папки із датами (використовуючи МОЇ конвенції про знайомства, блін ...)

Хтось знає відносно простий спосіб програмного отримання даних EXIF, таких як дата та час чи експозиція? Дякую!


Вбудована підтримка BCL для метаданих зображень досить обмежена. Я працюю з такими метаданими, як Exif, з 2002 року і маю просту, але потужну бібліотеку для вилучення таких даних для .NET .
Дрю Ноукс

1
Чому це було закрито? Він зосереджується на одній проблемі - отриманні EXIT із файлів. Є також чітка та цілеспрямована відповідь.
мафу

Відповіді:


23

Перегляньте цей екстрактор метаданих . Він написаний на Java, але також перенесений на C #. Я використав версію Java для написання невеликої утиліти для перейменування моїх файлів jpeg на основі тегів дати та моделі. Дуже проста у використанні.


Видалення метаданих EDIT також підтримує .NET. Це дуже швидка та проста бібліотека для доступу до метаданих із зображень та відео.

Він повністю підтримує Exif, а також IPTC, XMP та багато інших типів метаданих із типів файлів, включаючи JPEG, PNG, GIF, PNG, ICO, WebP, PSD, ...

var directories = ImageMetadataReader.ReadMetadata(imagePath);

// print out all metadata
foreach (var directory in directories)
foreach (var tag in directory.Tags)
    Console.WriteLine($"{directory.Name} - {tag.Name} = {tag.Description}");

// access the date time
var subIfdDirectory = directories.OfType<ExifSubIfdDirectory>().FirstOrDefault();
var dateTime = subIfdDirectory?.GetDateTime(ExifDirectoryBase.TagDateTime);

Він доступний через NuGet та код на GitHub .


Це чудово, якщо ваш додаток Windows завжди відображає зображення iPhone збоку або догори ногами. У Orientationкожному зображенні є тег, який зазвичай є магічним числом, але ця бібліотека повідомляє вам про обертання (тобто Rotate 180або Rotate 90 CCW).
Chris Akridge

47

Як пропонується, ви можете скористатися якоюсь сторонньою бібліотекою або зробити це вручну (що не так вже й багато роботи), але найпростішим і найбільш гнучким є, можливо, використання вбудованої функціональності в .NET. Докладніше див .:

Я кажу "це найбільш гнучко", оскільки .NET не намагається інтерпретувати або об'єднати дані будь-яким чином. Для кожного EXIF ​​ви в основному отримуєте масив байтів. Це може бути добре чи погано, залежно від того, наскільки сильно ви хочете контролю.

Крім того, я повинен зазначити, що перелік властивостей насправді не відповідає безпосередньо значенням EXIF. Сам EXIF ​​зберігається в декількох таблицях з перекриваються ідентифікаторами, але .NET розміщує все в одному списку та перевизначає ідентифікатори деяких елементів. Але поки ви не дбаєте про точні ідентифікатори EXIF, ви повинні бути в порядку з відображенням .NET.


Редагувати: Це можна зробити, не завантажуючи повне зображення, дотримуючись цієї відповіді: https://stackoverflow.com/a/552642/2097240


9
Для доступу до Bitmap.PropertyItems потрібно прочитати весь файл у пам’яті. Якщо ви створюєте растрову карту, отримуєте доступ до PropertyItems і не робите нічого іншого, ви можете скористатися XPerf, щоб переконатися, що ваша програма отримала доступ до файлу зображення та прочитала все це в пам'ять. Для мого комп'ютера файл розміром 3,4 Мб коштує> 700 мс на введення-виведення, лише щоб отримати EXIF ​​через PropertyItems :(.
Трістан,

4
Для порівняння, PhotoViewer Picasa зчитує лише 20-30 тис. Із кожного торкнутого файлу. Ці зчитування коштують лише ~ 25мс. Ого; Я хотів би поспілкуватися з хлопцем / дівчиною, які написали це. (Дані були зібрані шляхом профілювання запуску PhotoViewer за допомогою XPerf).
Трістан

@Tristan: Корисна інформація, однак як часто ви отримуєте доступ до метаданих зображення, не бажаючи також самого зображення? Я впевнений, що є деякі випадки, але я думаю, що в більшості випадків можна було б одночасно відображати зображення (або іншим чином працювати з його даними) І це метадані одночасно.
jrista

5
@jrista Як часто я хочу лише метадані? Більшу частину часу. Наприклад, уявіть, що ви хочете сортувати чи фільтрувати набір зображень за фрагментом метаданих. Сортування за датою взяття - досить поширена справа, і щоб отримати цю інформацію, потрібно увійти в метадані.
Трістан

1
Ця відповідь показує, як це зробити PropertyItems без завантаження всього зображення : stackoverflow.com/a/552642
Даніель Меллер


8

Ви можете використовувати TagLib #, який використовується такими програмами, як F-Spot . Окрім Exif, він буде читати значну кількість форматів метаданих для зображень, аудіо та відео.

Мені також подобається ExifUtils API, але він глючить і активно не розробляється.


5

Клас зображення має властивості PropertyItems та PropertyIdList. Ви можете ними користуватися.


Здається, він доступний лише для читання, тому я не можу додати жодного до нового зображення ...
TigrouMeow

3
Використовуйте функцію Image.SetPropertyItem (PropertyItem) на новому зображенні.
Мортен Крістіансен,

4

Отримання даних EXIF ​​із зображення JPEG передбачає:

  1. Звертаючись до маркерів JPEG, де згадується початок даних EXIF, наприклад, зазвичай oxFFE1 - це маркер, вставлений під час кодування даних EXIF, який є сегментом програми, куди надходять дані EXIF.
  2. Проаналізуйте всі дані, скажімо, від 0xFFE1 до 0xFFE2. Ці дані будуть потоком байтів у файлі, кодованому JPEG.
  3. Еквівалент цих байтів ASCII містив би різну інформацію, що стосується дати зображення, назви моделі камери, експозиції тощо ...

3

Інструмент командного рядка ExifTool від Філа Харві працює з десятками форматів зображень - включаючи велику кількість власних форматів RAW - і може маніпулювати різними форматами метаданих, включаючи EXIF, GPS, IPTC, XMP, JFIF.

Дуже простий у використанні, легкий, вражаючий додаток.


1
ExifTool - це дивовижна бібліотека / інструмент, але вона написана на Perl, тому використання її з C # передбачає запуск зовнішнього процесу.
Дрю Ноукс

0

Нещодавно я використовував цей .NET API метаданих . Я також написав про це запис у блозі , в якому показано читання, оновлення та видалення даних EXIF ​​із зображень за допомогою C #.

using (Metadata metadata = new Metadata("image.jpg"))
{
    IExif root = metadata.GetRootPackage() as IExif;
    if (root != null && root.ExifPackage != null)
    {
        Console.WriteLine(root.ExifPackage.DateTime);
     }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.