Cómo obtener los datos EXIF ​​de un archivo usando C #

77

Me gustaría escribir un pequeño programa en C # que revise mis fotos jpeg y, por ejemplo, las clasifique en carpetas con fecha (usando MIS convenciones de citas, maldita sea ...).

¿Alguien conoce una forma relativamente fácil de obtener los datos EXIF, como Fecha y hora o Exposición, mediante programación? ¡Gracias!

Joel en Gö
fuente
El soporte integrado de BCL para metadatos de imágenes es bastante limitado. He estado trabajando con metadatos como Exif desde 2002 y tengo una biblioteca simple pero poderosa para extraer dichos datos para .NET .
Drew Noakes
1
¿Por qué estaba esto cerrado? Se enfoca en un problema, obtener EXIT de los archivos. También hay una respuesta clara y enfocada.
mafu

Respuestas:

23

Consulte este extractor de metadatos . Está escrito en Java, pero también se ha adaptado a C #. He usado la versión de Java para escribir una pequeña utilidad para cambiar el nombre de mis archivos jpeg según las etiquetas de fecha y modelo. Muy facil de usar.


EDIT metadata-extractor también es compatible con .NET. Es una biblioteca muy rápida y sencilla para acceder a metadatos de imágenes y videos.

Es totalmente compatible con Exif, así como con IPTC, XMP y muchos otros tipos de metadatos de tipos de archivos, incluidos 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);

Está disponible a través de NuGet y el código está en GitHub .

Dave Griffiths
fuente
Esto es genial si su aplicación de Windows siempre muestra imágenes de iPhone de lado o al revés. Hay una Orientationetiqueta en cada imagen que normalmente es un número mágico, pero esta biblioteca le indica la rotación (es decir, Rotate 180o Rotate 90 CCW).
Chris Akridge
47

Como se sugirió, puede usar alguna biblioteca de terceros o hacerlo manualmente (lo cual no es mucho trabajo), pero lo más simple y flexible es quizás usar la funcionalidad incorporada en .NET. Para más ver:

Digo "es el más flexible" porque .NET no intenta interpretar o fusionar los datos de ninguna manera. Para cada EXIF, básicamente obtienes una matriz de bytes. Esto puede ser bueno o malo dependiendo de cuánto control desee realmente.

Además, debo señalar que la lista de propiedades no corresponde directamente a los valores EXIF. EXIF en sí mismo se almacena en varias tablas con ID superpuestos, pero .NET pone todo en una lista y redefine las ID de algunos elementos. Pero siempre que no le interesen los ID EXIF ​​precisos, debería estar bien con el mapeo .NET.


Editar: Es posible hacerlo sin cargar la imagen completa siguiendo esta respuesta: https://stackoverflow.com/a/552642/2097240

Jan Zich
fuente
9
El acceso a Bitmap.PropertyItems requiere leer todo el archivo en la memoria. Si crea un mapa de bits, accede a PropertyItems y no hace nada más, puede usar XPerf para ver que su aplicación accedió al archivo de imagen y leerlo todo en la memoria. Para mi computadora, un archivo de 3.4mb cuesta> 700ms por valor de IO, solo para obtener EXIF ​​a través de PropertyItems :(.
Tristan
4
En comparación, PhotoViewer de Picasa lee solo 20 - 30k de cada archivo que toca. Esas lecturas cuestan solo ~ 25ms. Guau; Me encantaría charlar con el chico / chica que escribió esas cosas. (Los datos se recopilaron perfilando el inicio de PhotoViewer utilizando XPerf).
Tristan
@Tristan: Información útil, sin embargo, ¿con qué frecuencia accedes a los metadatos de la imagen sin querer la imagen en sí? Estoy seguro de que hay algunos casos, pero creo que en la mayoría de los casos, uno estaría mostrando la imagen (o trabajando con sus datos) Y sus metadatos al mismo tiempo.
jrista
5
@jrista ¿Con qué frecuencia quiero solo los metadatos? La mayor parte del tiempo Por ejemplo, imagina que quieres ordenar o filtrar un conjunto de imágenes por un fragmento de metadatos. Ordenar por fecha de captura es algo bastante común, y para obtener esa información debes ingresar a los metadatos.
Tristan
1
Esta respuesta muestra cómo hacerlo PropertyItems sin cargar la imagen completa : stackoverflow.com/a/552642
Daniel Möller
8

Puede utilizar TagLib #, que utilizan aplicaciones como F-Spot . Además de Exif, leerá una buena cantidad de formatos de metadatos para imagen, audio y video.

También me gusta la API de ExifUtils, pero tiene errores y no se desarrolla activamente.

smola
fuente
5

La clase Image tiene propiedades PropertyItems y PropertyIdList. Puedes usarlos.

idursun
fuente
Parece que es de solo lectura, por lo que no puedo agregar ninguna en la nueva imagen ...
TigrouMeow
3
Utilice la función Image.SetPropertyItem (PropertyItem) en la nueva imagen.
Morten Christiansen
4

Obtener datos EXIF ​​de una imagen JPEG implica:

  1. Buscando los marcadores JPEG que mencionan el comienzo de los datos EXIF ​​,. por ejemplo, normalmente oxFFE1 es el marcador insertado mientras se codifican datos EXIF, que es un segmento de aplicación, donde van los datos EXIF.
  2. Analice todos los datos desde, por ejemplo, 0xFFE1 a 0xFFE2. Estos datos serían un flujo de bytes, en el archivo codificado en JPEG.
  3. El equivalente ASCII de estos bytes contendría diversa información relacionada con la fecha de la imagen, el nombre del modelo de la cámara, la exposición, etc.
dorado
fuente
3

La herramienta de línea de comandos ExifTool de Phil Harvey funciona con docenas de formatos de imágenes, incluidos muchos formatos RAW patentados, y puede manipular una variedad de formatos de metadatos, incluidos EXIF, GPS, IPTC, XMP, JFIF.

Aplicación impresionante, ligera y muy fácil de usar.

Kirk Broadhurst
fuente
1
ExifTool es una biblioteca / herramienta asombrosa, pero está escrita en Perl, por lo que usarla desde C # implica iniciar un proceso externo.
Drew Noakes
0

Recientemente, utilicé esta API de metadatos .NET . También escribí una publicación de blog al respecto, que muestra cómo leer, actualizar y eliminar los datos EXIF ​​de las imágenes usando 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);
     }
}
Shoaib Khan
fuente