c# - una - metadatos fotos online
¿Cómo puedo saber cuándo se tomó una foto en C#corriendo en Vista? (8)
En Windows XP, "FileInfo.LastWriteTime" devolverá la fecha en que se tomó una fotografía, sin importar cuántas veces se movió el archivo en el sistema de archivos.
En Vista, en cambio, devuelve la fecha en que se copió la imagen de la cámara.
¿Cómo puedo saber cuándo se toma una foto en Vista? En Windows Explorer este campo se conoce como "Fecha de toma".
En Windows XP, "FileInfo.LastWriteTime" devolverá la fecha en que se tomó una fotografía, sin importar cuántas veces se movió el archivo en el sistema de archivos.
Tengo grandes dudas de que XP realmente estaba haciendo eso. Lo más probable es que la herramienta que utilizó para copiar la imagen de la cámara a su disco duro restableció la fecha de modificación del archivo a la Fecha de toma de la imagen.
Con WPF y C # puede obtener la propiedad Fecha de toma utilizando la clase BitmapMetadata:
Habrá datos EXIF incrustados en la imagen. Hay un montón de ejemplos en la web si busca EXIF y C #.
deberás verificar la información EXIF de la imagen. No creo que con las funciones regulares de .Net sabrá cuando se tomó la foto.
Puede ser un poco complicado ...
//retrieves the datetime WITHOUT loading the whole image
public static DateTime GetDateTakenFromImage(string path)
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
using (Image myImage = Image.FromStream(fs, false, false))
{
PropertyItem propItem = null;
try
{
propItem = myImage.GetPropertyItem(36867);
}
catch { }
if (propItem != null)
{
string dateTaken = r.Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2);
return DateTime.Parse(dateTaken);
}
else
return new FileInfo(path).LastWriteTime;
}
}
Mantuve una biblioteca de código abierto simple desde 2002 para extraer metadatos de archivos de imagen / video.
// 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 DateTime tag value
var dateTime = subIfdDirectory?.GetDateTime(ExifDirectoryBase.TagDateTimeOriginal);
En mis puntos de referencia, este código se ejecuta 12 veces más rápido que Image.GetPropertyItem
, y alrededor de 17 veces más rápido que WPF JpegBitmapDecoder
/ BitmapMetadata
API.
Hay una tonelada de información adicional disponible de la biblioteca, como ajustes de la cámara (F-stop, ISO, velocidad de obturación, modo de flash, distancia focal, ...), propiedades de la imagen (dimensiones, configuraciones de píxeles) y otras cosas como posiciones de GPS , palabras clave, información de copyright, etc.
Si solo está interesado en los metadatos, el uso de esta biblioteca es muy rápido ya que no decodifica la imagen (es decir, mapa de bits). Puede escanear miles de imágenes en unos segundos si tiene un almacenamiento lo suficientemente rápido.
ImageMetadataReader
comprende muchos tipos de archivos (JPEG, PNG, GIF, BMP, TIFF, PCX, WebP, ICO, ...). Si sabe que está tratando con JPEG, y solo quiere datos Exif, puede hacer que el proceso sea aún más rápido con lo siguiente:
var directories = JpegMetadataReader.ReadMetadata(stream, new[] { new ExifReader() });
La biblioteca de metadatos-extractores está disponible a través de NuGet y el código está en GitHub . Gracias a todos los colaboradores increíbles que han mejorado la biblioteca y enviado imágenes de prueba a lo largo de los años.
Image myImage = Image.FromFile(@"C:/temp/IMG_0325.JPG");
PropertyItem propItem = myImage.GetPropertyItem(306);
DateTime dtaken;
//Convert date taken metadata to a DateTime object
string sdate = Encoding.UTF8.GetString(propItem.Value).Trim();
string secondhalf = sdate.Substring(sdate.IndexOf(" "), (sdate.Length - sdate.IndexOf(" ")));
string firsthalf = sdate.Substring(0, 10);
firsthalf = firsthalf.Replace(":", "-");
sdate = firsthalf + secondhalf;
dtaken = DateTime.Parse(sdate);
Aquí es tan rápido y limpio como puedas obtenerlo. Al usar FileStream, puedes decirle a GDI + que no cargue toda la imagen para su verificación. Corre más de 10 veces más rápido en mi máquina.
//we init this once so that if the function is repeatedly called
//it isn''t stressing the garbage man
private static Regex r = new Regex(":");
//retrieves the datetime WITHOUT loading the whole image
public static DateTime GetDateTakenFromImage(string path)
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
using (Image myImage = Image.FromStream(fs, false, false))
{
PropertyItem propItem = myImage.GetPropertyItem(36867);
string dateTaken = r.Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2);
return DateTime.Parse(dateTaken);
}
}
Y sí, la identificación correcta es 36867, no 306.
Los otros proyectos de código abierto a continuación deben tomar nota de esto. ¡es un GRAN impacto de rendimiento al procesar miles de archivos!