it-swarm.com.de

Wie kann ich herausfinden, wann ein Bild tatsächlich in C # unter Vista aufgenommen wurde?

In Windows XP gibt "FileInfo.LastWriteTime" das Aufnahmedatum zurück - unabhängig davon, wie oft die Datei im Dateisystem verschoben wird.

In Vista wird stattdessen das Datum zurückgegeben, an dem das Bild von der Kamera kopiert wurde.

Wie kann ich herausfinden, wann ein Bild in Vista aufgenommen wurde? In Windows Explorer wird dieses Feld als "Aufnahmedatum" bezeichnet.

42
sepang

Hier ist so schnell und sauber wie Sie es bekommen können. Mit FileStream können Sie GDI + anweisen, nicht das gesamte Bild zur Überprüfung zu laden. Es läuft über 10x so schnell auf meiner Maschine.

    //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);
        }
    }

Und ja, die richtige ID ist 36867, nicht 306.

Die anderen unten aufgeführten Open-Source-Projekte sollten dies berücksichtigen. Es ist ein riesiger Performance-Hit, wenn Tausende von Dateien verarbeitet werden!

90
kDar
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);
10
sepang

Ich unterhielt seit 2002 eine einfache Open-Source-Bibliothek , um Metadaten aus Bild-/Videodateien zu extrahieren.

// 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);

In meinen Benchmarks ist dieser Code 12-mal schneller als Image.GetPropertyItem und rund 17-mal schneller als die WPF JpegBitmapDecoder/BitmapMetadata-API.

Es gibt eine Tonne zusätzlicher Informationen aus der Bibliothek, wie Kameraeinstellungen (Blendenwert, ISO, Verschlusszeit, Blitzmodus, Brennweite, ...), Bildeigenschaften (Abmessungen, Pixelkonfigurationen) und andere Dinge wie GPS-Positionen , Schlüsselwörter, Copyright-Informationen usw.

Wenn Sie nur an den Metadaten interessiert sind, ist die Verwendung dieser Bibliothek sehr schnell, da das Bild nicht dekodiert wird (d. H. Bitmap). Wenn Sie schnell genug Speicherplatz haben, können Sie in wenigen Sekunden Tausende von Bildern scannen.

ImageMetadataReader versteht viele Dateitypen (JPEG, PNG, GIF, BMP, TIFF, PCX, WebP, ICO, ...). Wenn Sie wissen wissen, dass Sie mit JPEG zu tun haben und Sie only mit Exif-Daten arbeiten möchten, können Sie den Vorgang mit folgenden Schritten noch beschleunigen:

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

Die Metadata-Extractor -Bibliothek ist über NuGet und die Codes von GitHub verfügbar. Vielen Dank an alle tollen Mitwirkenden, die die Bibliothek verbessert und Testbilder über die Jahre eingereicht haben.

6
Drew Noakes

Mit WPF und C # können Sie die Date Taken-Eigenschaft mithilfe der BitmapMetadata-Klasse abrufen:

MSDN - BitmapMetada

WPF und BitmapMetadata

5
DaveK

In Windows XP "FileInfo.LastWriteTime" Wird das Datum zurückgegeben, an dem ein Bild Aufgenommen wird - unabhängig davon, wie oft Die Datei im Ordner verschoben wird Dateisystem.

Ich habe große Zweifel, dass XP dies tatsächlich tat. Es ist wahrscheinlicher, dass das Werkzeug, mit dem Sie das Bild von der Kamera auf Ihre Festplatte kopiert haben, das Datum der geänderten Datei auf das Aufnahmedatum des Bildes zurückgesetzt hat.

2
James Curran

sie müssen die EXIF-Informationen aus dem Bild überprüfen. Ich denke nicht, dass Sie mit normalen .Net-Funktionen wissen, wann das Bild aufgenommen wurde.

Es könnte etwas kompliziert werden ...

1
Miles

Im Bild werden EXIF-Daten eingebettet. Es gibt viele Beispiele im Web, wenn Sie nach EXIF ​​und C # suchen.

1
Paul Hammond
    //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;
        }
    }
0
Peter Redei