Laden...

EXIF Fotometadaten auslesen

Erstellt von easy867 vor 5 Jahren Letzter Beitrag vor 5 Jahren 6.874 Views
Thema geschlossen
E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren
EXIF Fotometadaten auslesen

Guten Tag alle zusammen. Dies ist mein erster Beitrag hier im Forum und ich freue mich ein Teil dieser Community zu sein.

Ich bin aktuell dabei mit C# Fotometadaten auszulesen.
Das ganze habe ich schon in VBA realisiert aber möchte das nun in C# umsetzen.

Das eigentliche Ziel: Es soll mit einem C# Programm aus einem definiertem Verzeichnis folgende Meta Daten von 360° Fotos und normalen Fotos ausgelesen und in einer Excel Tabelle gespeichert werden:

Dateiname
GPS Position
Aufnahmedatum
Autor
Dies soll zunächst auf Anforderung passieren, später soll das Programm von einem Server regelmäßig eigenständig ausgeführt werden.

Im Anhang befindet sich auch mein aktuelles VBA Skript.(Excel-Datei)

Ich bin schon während meinen Recherchen auf MetadataExtractor gestoßen und würde gerne eure Meinungen dazu wissen. Über weitere Tipps/Ideen würde ich mich sehr freuen.

Hinweis von Coffeebean vor 5 Jahren

Anhang entfernt [Hinweis] Wie poste ich richtig?

S
324 Beiträge seit 2007
vor 5 Jahren

Jup, ich habe dafür auch den MetadataExtractor verwendet.
Irgendwelche Fragen dazu? 😉

Ich hab mir die Infos in ein Dict gepackt und entnehme dann dort diese, welche ich brauche:


Dictionary<string, string> ExifInfos = new Dictionary<string, string>();
IEnumerable<MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(Path.Combine(_cnf.imagePath, imageFileName));
foreach (var directory in directories)
{
	foreach (var tag in directory.Tags)
	{
		if (!ExifInfos.ContainsKey(tag.Name))
		{
			ExifInfos.Add(tag.Name, tag.Description);
		}
	}
}

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Ich bin auch noch nicht so mit VisualStudio 2013 und C# vertraut, sodass kleine Probleme mich leider schon akuell lange aufhalten.

Ich habe mir nun dieses package runtergeladen :https://www.nuget.org/packages/MetadataExtractor/

Das sollte ja eigentlich alle benötigen Bibs enthalten.
Zudem habe ich den Paket-Manager installiert.

Aktuelles Problem beim Einbinden deines Codes:

Fehlermeldung:
Error 1 A namespace cannot directly contain members such as fields or methods c:\users\UserName\documents\visual studio 2013\Projects\Metadataextractor\Metadataextractor\Program.cs 1 1 Metadataextractor
Error 2 Expected class, delegate, enum, interface, or struct c:\users\UserName\documents\visual studio 2013\Projects\Metadataextractor\Metadataextractor\Program.cs 1 44 Metadataextractor

Und muss ich dann für den Extraktor eine Windows Forms Application erstellen oder was wäre in diesem Fall richtig ?

Grüße

S
324 Beiträge seit 2007
vor 5 Jahren

Ach du je... da fehlen ja noch viele, viele Grundlagen 😕

Also nein, du musst keine Winform Anwendung dafür nutzen, geht genauso gut auch in einer reinen Konsolenanwendung.
Aber ohne den Code zu sehen, kann man schlecht helfen.

Andere Frage: warum nutzt du VS2013? Aktuell ist VS2017 😉

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Hey,
ich habe vorerst nur deinen Code verwendet um das ganze einfach mal zu testen.

Dictionary<string, string> ExifInfos = new Dictionary<string, string>();
IEnumerable<MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(Path.Combine(_cnf.imagePath, imageFileName));
foreach (var directory in directories)
{
    foreach (var tag in directory.Tags)
    {
        if (!ExifInfos.ContainsKey(tag.Name))
        {
            ExifInfos.Add(tag.Name, tag.Description);
        }
    }
}

2013, da ich davon die Vollversion besitze und 2017 Konflikte mit Outlook und Office 2013 hervorruft.

S
324 Beiträge seit 2007
vor 5 Jahren

... dann fehlen dir wirklich noch viele, viele Grundlagen.
Wenn du erst mit c# anfängst, dann beschäftige dich erst mal damit wie eine Programm und darin eine Klasse / *.cs Datei aufgebaut ist.

Das was ich hier rein kopiert habe, ist der Inhalt einer Methode - das funktioniert nicht wenn man das einfach nur kopiert und in irgendeine Datei "rein klatscht" 😕

Und zum Rest... mit wäre nicht bekannst das VS2017 probleme in Verbindung mit Office2013 macht.
Alternativ in der Pro version vll die Office Integrationen nicht mit installieren.
Alternativ zur Pro gibt es auch die Community, welche fast einen Identischen Funktionsumfang hat, aber bis zu einer bestimmten Limitierung (Mitarbeiter/Umsatz) kostenfrei verfügbar ist.
Alternativ dazu gibt es auch (noch) die VS 2017 Express für Windows Desktop, welche auch kommerziell komplett kostenfrei genutzt werden darf.

P
441 Beiträge seit 2014
vor 5 Jahren

Alternativ dazu gibt es auch (noch) die VS 2017 Express für Windows Desktop, welche auch kommerziell komplett kostenfrei genutzt werden darf.

Von VS 2017 gibt es keine Express Versionen mehr. Lediglich Community, Professional und Enterprise.

Edit: Ich revidiere.. die gibts ja tatsächlich noch.

2.298 Beiträge seit 2010
vor 5 Jahren

Um auf dem aktuellsten Stand zu sein, sollte der TE dennoch die Community-Edition nutzen.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Hey ihr habt natürlich voll Recht. Ich habe nun auch Tutorials durchgearbeitet und weitere werden folgen.
Sorry dafür.

Trotzdem besteht aktuell die Frage, warum der mir bei dem Beispiel aus dem Github Download so viele Fehler raus haut. Einige konnte ich schon beseitigen aber es bleibt ein Rest bestehen.
Download: https://github.com/drewnoakes/metadata-extractor-dotnet/tree/master/MetadataExtractor.Samples

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using MetadataExtractor.Formats.Exif;
using MetadataExtractor.Formats.Iptc;
using MetadataExtractor.Formats.Jpeg;

#pragma warning disable 8321

namespace MetadataExtractor.Samples
{
    /// <summary>
    /// Showcases the most popular ways of using the MetadataExtractor library.
    /// </summary>
    /// <remarks>
    /// For more information, see the project wiki:
    /// <para />
    /// https://github.com/drewnoakes/metadata-extractor/wiki/GettingStarted
    /// </remarks>
    internal static class Program
    {
        private static void Main()
        {
            const string filePath = "../MetadataExtractor.Tests/Data/withIptcExifGps.jpg";

            Console.WriteLine("Processing file: {filePath}");

            // There are multiple ways to get a Metadata object for a file

            //
            // SCENARIO 1: UNKNOWN FILE TYPE
            //
            // This is the most generic approach.  It will transparently determine the file type and invoke the appropriate
            // readers.  In most cases, this is the most appropriate usage.  This will handle JPEG, TIFF, GIF, BMP and RAW
            // (CRW/CR2/NEF/RW2/ORF) files and extract whatever metadata is available and understood.
            //
            try
            {
                var directories = ImageMetadataReader.ReadMetadata(filePath);

                Print(directories, "Using ImageMetadataReader");
            }
            catch (ImageProcessingException e)
            {
                PrintError(e);
            }
            catch (IOException e)
            {
                PrintError(e);
            }

            //
            // SCENARIO 2: SPECIFIC FILE TYPE
            //
            // If you know the file to be a JPEG, you may invoke the JpegMetadataReader, rather than the generic reader
            // used in approach 1.  Similarly, if you knew the file to be a TIFF/RAW image you might use TiffMetadataReader,
            // PngMetadataReader for PNG files, BmpMetadataReader for BMP files, or GifMetadataReader for GIF files.
            //
            // Using the specific reader offers a very, very slight performance improvement.
            //
            try
            {
                var directories = JpegMetadataReader.ReadMetadata(filePath);

                Print(directories, "Using JpegMetadataReader");
            }
            catch (JpegProcessingException e)
            {
                PrintError(e);
            }
            catch (IOException e)
            {
                PrintError(e);
            }

            //
            // APPROACH 3: SPECIFIC METADATA TYPE
            //
            // If you only wish to read a subset of the supported metadata types, you can do this by
            // passing the set of readers to use.
            //
            // This currently only applies to JPEG file processing.
            //
            try
            {
                // Handle only Exif and IPTC from JPEG
                var readers = new IJpegSegmentMetadataReader[] { new ExifReader(), new IptcReader() };

                var directories = JpegMetadataReader.ReadMetadata(filePath, readers);

                Print(directories, "Using JpegMetadataReader for Exif and IPTC only");
            }
            catch (JpegProcessingException e)
            {
                PrintError(e);
            }
            catch (IOException e)
            {
                PrintError(e);
            }}

            // Write all extracted values to stdout
            void Print(IEnumerable<Directory> directories, string method)
            {
                Console.WriteLine();
                Console.WriteLine("-------------------------------------------------");
                Console.Write(' '); Console.WriteLine(method);
                Console.WriteLine("-------------------------------------------------");
                Console.WriteLine();

                // Extraction gives us potentially many directories
                foreach (var directory in directories)
                {
                    // Each directory stores values in tags
                    foreach (var tag in directory.Tags)
                        Console.WriteLine(tag);

                    // Each directory may also contain error messages
                    foreach (var error in directory.Errors)
                        Console.Error.WriteLine("ERROR: " + error);
                }
            }

            DateTime? GetTakenDateTime(IEnumerable<Directory> directories)
            {
                // obtain the Exif SubIFD directory
                var directory = directories.OfType<ExifSubIfdDirectory>().FirstOrDefault();

                if (directory == null)
                    return null;

                // query the tag's value
                if (directory.TryGetDateTime(ExifDirectoryBase.TagDateTimeOriginal, out var dateTime))
                {
                    return dateTime;
                }
                return null;
            }

            string GetExposureProgramDescription(IEnumerable<Directory> directories)
            {
                // obtain a specific directory
                var directory = directories.OfType<ExifSubIfdDirectory>().FirstOrDefault();

                if (directory == null)
                    return null;

                // create a descriptor
                var descriptor = new ExifSubIfdDescriptor(directory);

                // get tag description
                return descriptor.GetExposureProgramDescription();
            }

            void PrintError(Exception exception) => Console.Error.WriteLine("EXCEPTION: {exception}");
        }
    }
}

Fehlermeldung:
Warning 1 '8321' is not a valid warning number C:\Users\UserName\Desktop\BIM\GEO\C#\metadata-extractor-dotnet-master\MetadataExtractor.Samples\Program.cs 9 25
Error 5 ) expected C:\Users\UserName\Desktop\BIM\GEO\C#\metadata-extractor-dotnet-master\MetadataExtractor.Samples\Program.cs 134 93
Error 2 ; expected C:\Users\UserName\Desktop\BIM\GEO\C#\metadata-extractor-dotnet-master\MetadataExtractor.Samples\Program.cs 156 50
Error 7 ; expected C:\Users\UserName\Desktop\BIM\GEO\C#\metadata-extractor-dotnet-master\MetadataExtractor.Samples\Program.cs 134 101
Error 9 ; expected C:\Users\UserName\Desktop\BIM\GEO\C#\metadata-extractor-dotnet-master\MetadataExtractor.Samples\Program.cs 134 102
Error 10 ; expected C:\Users\UserName\Desktop\BIM\GEO\C#\metadata-extractor-dotnet-master\MetadataExtractor.Samples\Program.cs 134 103
Error 6 Invalid expression term ')' C:\Users\UserName\Desktop\BIM\GEO\C#\metadata-extractor-dotnet-master\MetadataExtractor.Samples\Program.cs 134 101
Error 8 Invalid expression term ')' C:\Users\UserName\Desktop\BIM\GEO\C#\metadata-extractor-dotnet-master\MetadataExtractor.Samples\Program.cs 134 102
Error 3 Invalid token '(' in class, struct, or interface member declaration C:\Users\UserName\Desktop\BIM\GEO\C#\metadata-extractor-dotnet-master\MetadataExtractor.Samples\Program.cs 156 76
Error 4 Type or namespace definition, or end-of-file expected C:\Users\UserName\Desktop\BIM\GEO\C#\metadata-extractor-dotnet-master\MetadataExtractor.Samples\Program.cs 159 1

D
261 Beiträge seit 2015
vor 5 Jahren

Weil dein altes Visual Studio die in dem Quellcode verwendeten neuen Sprachfeatures nicht unterstützt.

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Moin allerseits,

So 2017 ist auch installiert und damit funktioniert es auch...
Bekomme auch damit schon einige Metadaten angezeigt, konnte es schon um einiges minimieren aber immernoch zu viele:D

Wie lege ich denn nun fest,, dass ich wirklich nur Name, Pfad, Erstelldatum und GPS-Koordinaten angezeigt bekomme ?

So sieht es aktuell aus:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using MetadataExtractor.Formats.Exif;
using MetadataExtractor.Formats.Iptc;
using MetadataExtractor.Formats.Jpeg;

#pragma warning disable 8321

namespace MetadataExtractor.Samples
{
    
    internal static class Program
    {
        private static void Main()
        {
            const string filePath = "C:/Users/UserName/Desktop/Neuer Ordner/V0050006.JPG";

            Console.WriteLine($"Processing file: {filePath}");

         
            try
            {
                // Handle only Exif and IPTC from JPEG
                var readers = new IJpegSegmentMetadataReader[] { new ExifReader(), new IptcReader() };

                var directories = JpegMetadataReader.ReadMetadata(filePath, readers);

                Print(directories, "Using JpegMetadataReader for Exif and IPTC only");
            }
            catch (JpegProcessingException e)
            {
                PrintError(e);
            }
            catch (IOException e)
            {
                PrintError(e);
            }
            
           
            // Write all extracted values to stdout
            void Print(IEnumerable<Directory> directories, string method)
            {
                Console.WriteLine();
                Console.WriteLine("-------------------------------------------------");
                Console.Write(' '); Console.WriteLine(method);
                Console.WriteLine("-------------------------------------------------");
                Console.WriteLine();



                // Extraction gives us potentially many directories
                foreach (var directory in directories)
                {
                    // Each directory stores values in tags
                    foreach (var tag in directory.Tags)
                        Console.WriteLine(tag);

                    // Each directory may also contain error messages
                    foreach (var error in directory.Errors)
                        Console.Error.WriteLine("ERROR: " + error);
                }
            }


            void PrintError(Exception exception) => Console.Error.WriteLine($"EXCEPTION: {exception}");
        }
    }
}

Würde mich über Hilfe freuen.

Liebe Grüße

16.806 Beiträge seit 2008
vor 5 Jahren

Was für Hilfe erwartest Du denn? Dass wir Dir jetzt den Code schreiben? 🤔

Schau Dir doch die entsprechenden Klasse an und verwende die Informationen, die die Klassen und Eigenschaften zur Verfügung stellen.
Ist doch zudem alles Open Source - schau in den Code.

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Nein das möchte ich garantiert nicht.
Nur finde ich keinen weiteren Ansatz, wie ich wirklich nur Name, Pfad, Datum und GPS Daten anzeigen lassen kann. 🤔

4.931 Beiträge seit 2008
vor 5 Jahren

Indem du statt der Schleife über alle Tags eben nur die 4 einzelnen Werte ausliest. Dafür gibt es (wohl) die Methode GetObject:


int tagType;
Console.WriteLine(directory.GetObject(tagType));

Du muß jetzt nur noch die entsprechenden TagTypes für die 4 Werte heraussuchen (bzw. herausfinden).

5.657 Beiträge seit 2006
vor 5 Jahren

Schau dir doch mal im Debugger (und in der Doku) an, welche Daten zurückgegeben werden. Tag ist eine Datenstruktur, und hat einen Namen und einen Wert. Wenn du die Namen der von dir gewünschten Tags hast, kannst du danach filtern.

[Artikel] Debugger: Wie verwende ich den von Visual Studio?
[Tipp] Schau in die Doku! - Möglichkeiten der Informationsgewinnung

Weeks of programming can save you hours of planning

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Moin Moin,

Danke nochmals für eure bisherige Hilfe.

Die entsprechenden Tags habe ich herausgefunden. Es werden auch einige angezeigt, jedoch gibt es bei den GPS Daten und dem Pfad Anzeigeprobleme.
Womit könnte das zusammen hängen ?

Im Anhang auch einen Ausschnitt der aktuellen Ausgabe um das Problem besser darzustellen.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using MetadataExtractor.Formats.Exif;
using MetadataExtractor.Formats.Iptc;
using MetadataExtractor.Formats.Jpeg;

#pragma warning disable 8321

namespace MetadataExtractor.Samples
{

    internal static class Program
    {
        
        private static void Main()
        {
            const string filePath = "C:/Users/UserName/Desktop/Neuer Ordner/V0050006.JPG";

            Console.WriteLine($"Processing file: {filePath}");
            
            try
            {
                // Handle only Exif and IPTC from JPEG
                var readers = new IJpegSegmentMetadataReader[] { new ExifReader(), new IptcReader() };

                var directories = JpegMetadataReader.ReadMetadata(filePath, readers);

                Print(directories, "Using JpegMetadataReader for Exif and IPTC only");
            }
            catch (JpegProcessingException e)
            {
                PrintError(e);
            }
            catch (IOException e)
            {
                PrintError(e);
            }

 

            // Write all extracted values to stdout
            void Print(IEnumerable<Directory> directories, string method)
            {
                Console.WriteLine();
                Console.WriteLine("-------------------------------------------------");
                Console.Write(' '); Console.WriteLine(method);
                Console.WriteLine("-------------------------------------------------");
                Console.WriteLine();
                
                // Extraction gives us potentially many directories
                foreach (var directory in directories)
                {
                        Console.WriteLine(directory.GetObject(271));//cameraname
                        Console.WriteLine(directory.GetObject(306));//date
                        Console.WriteLine(directory.GetObject(1));//gpslatituderef N
                        Console.WriteLine(directory.GetObject(2));//latitude
                        Console.WriteLine(directory.GetObject(3));//longituderef E
                        Console.WriteLine(directory.GetObject(4));//longitude
                        Console.WriteLine(directory.GetObject(315));//artist
                        Console.WriteLine(directory.GetObject(32781));//image id full path

                }   
            }
        
         void PrintError(Exception exception) => Console.Error.WriteLine($"EXCEPTION: {exception}");
         
        }

    }
}

Liebe Grüße und einen guten Start in die neue Woche 😁

4.931 Beiträge seit 2008
vor 5 Jahren

Nicht alles sind unbedingt Strings (daher ja auch object als Datentyp). Einige davon sind anscheinend binär (daher erscheint System.Byte[] in der Ausgabe).

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Naja ich denke das es eher an dem rationalen Datentyp der GPS Daten liegt oder ?
Gibt es dafür eine Methode um das umzurechnen (BSP. toString) ?

Alle anderen sind vom Typ ASCII also als String realisierbar.
Wobei der Pfad als String auch noch Probleme bereitet, wie auf dem Bild zu sehen ist.

Würde mich über Hilfe sehr freuen.

Liebe Grüße 🙂


            string cameraname;
            string date;
            string latituderef;
            string longituderef;
            string artist;
            string path;
            string latitude;
            string longitude;

foreach (var directory in directories)
                {
                     cameraname = directory.GetString(271);//cameraname
                    Console.WriteLine(cameraname);

                    date = directory.GetString(306);
                    Console.WriteLine(date);//date

                    latituderef = directory.GetString(1);
                    Console.WriteLine(latituderef);//gpslatituderef N

                    latitude = directory.GetObject(2).ToString();
                    Console.WriteLine(directory.GetObject(2));//latitude

                    longituderef = directory.GetString(3);
                    Console.WriteLine(longituderef);//longituderef E

                    longitude = directory.GetObject(4).ToString();
                    Console.WriteLine(longitude);//longitude

                    artist = directory.GetString(315);
                    Console.WriteLine(artist);//artist

                    path = directory.GetString(32781);
                    Console.WriteLine(path);//image id full path


                }
4.931 Beiträge seit 2008
vor 5 Jahren

Bei dem Datentyp kannst du ja einfach folgendes benutzen:


MetadataExtractor.Rational[] data = directory.GetObject(...) as MetadataExtractor.Rational[];

Und dann für die einzelnen Arrayelemente (Rational) die passenden Daten ausgeben (entweder auch direkt ToString() oder aber die Eigenschaften überprüfen).

Nur bei einem Byte-Array mußt du halt genau wissen, wie die Sachen kodiert sind, um eine passende Ausgabe hinzukriegen (im allgemeinen Fall einfach als HEX-String).

Was ist denn an dem Pfad (bzw. Namen) "V005006.JPG" problematisch?
Die Daten darunter scheinen ja wieder "cameraname" und "date" des nächsten Datensatzes zu sein.
Am besten du setzt am Anfang und Ende eines Datensatzes noch ein paar Trennzeichen in die Ausgabe.

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Naja der Pfad müsste ja eigentlich wie folgt aussehen: C:/Users/UserName/Desktop/Neuer Ordner/V0050006.JPG

Und bei dem Rational verstehe ich aber noch nicht ganz wie das aufgebaut ist. 🤔
Letztendlich möchte ich ja Längen und Breitengrad so angezeigt bekommen: 43,120881
Daher möchte ich letztendlich aus dem Array(Rational) ,,eine" Zahl erzeugen, sodass ich damit auch weiter arbeiten kann. Also quasi das Array als String oder Double.


MetadataExtractor.Rational[] data = directory.GetObject(2) as MetadataExtractor.Rational[];
latitude = data.ToString();
Console.WriteLine(latitude);//latitude

4.931 Beiträge seit 2008
vor 5 Jahren

s. How to parse EXIF GPS information to lat,lng decimal numbers.
Also, so wie ich das verstehe, sind es dann 1-3 Rational-Werte (degrees, minutes and decimal seconds).

Und der Datentyp Rational besteht intern einfach aus zwei Werten (Nenner, Zähler): Rational.cs.

Um daraus dann einen Wert zu erhalten, s. Kommentar im obigen Link:

dd=x0+x1/60+x2/3600

5.657 Beiträge seit 2006
vor 5 Jahren

Also was an der Pfadangabe nicht stimmt, mußt du nochmal erklären.

Zum Rational sagt die Doku:

Specifies that the value data member is an array of pairs of unsigned long integers. Each pair represents a fraction; the first integer is the numerator and the second integer is the denominator.

Ich nehme an, daß es pro GPS-Koordinate jeweils drei Paare sind: Degrees, Minutes und Seconds. Genaueres kannst du mit dem Debugger oder der Doku der von dir verwendeten Bibliothek herausfinden. Zum Parsen kannst du die BitConverter-Methoden benutzen, wie BitConverter.ToUInt32.

[Artikel] Debugger: Wie verwende ich den von Visual Studio?
[Tipp] Schau in die Doku! - Möglichkeiten der Informationsgewinnung

Weeks of programming can save you hours of planning

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Guten Morgen,

Also ich bin auf folgende Umrechnung gestoßen und habe versucht das bei mir einzubinden.
Ich hätte nun gedacht, dass ,,imageProperties"durch directory.. wie in der ersten Zeile ersetzt wird.
Naja falsch gedacht 😁
Muss ich dafür nun mit imageproperties/PropertyItems arbeiten, oder kann ich das auch auf meine bereits verwendeten Suchen Bsp. directory.GetRationalArray(2) anwenden ? 🤔

Grüße

double LatDegrees = (BitConverter.ToUInt32(directory.GetRationalArray(2).Value, 0) / (BitConverter.ToUInt32(imageProperties.GetPropertyItem(2).Value, 4)));
                    double LatMinutes = (BitConverter.ToUInt32(directory.GetPropertyItem(2).Value, 8)) / (BitConverter.ToUInt32(imageProperties.GetPropertyItem(2).Value, 12));
                    double LatSeconds = (BitConverter.ToUInt32(imageProperties.GetPropertyItem(2).Value, 16)) / (BitConverter.ToUInt32(imageProperties.GetPropertyItem(2).Value, 20));
                    latitude = LatDegrees + LatMinutes / 60 + LatSeconds / 3600;
                    Console.WriteLine(latitude);//latitude

                    double LonDegrees = ((BitConverter.ToUInt32(imageProperties.GetPropertyItem(4).Value, 0)) / (BitConverter.ToUInt32(imageProperties.GetPropertyItem(4).Value, 4)));
                    double LonMinutes = (BitConverter.ToUInt32(imageProperties.GetPropertyItem(4).Value, 8)) / (BitConverter.ToUInt32(imageProperties.GetPropertyItem(4).Value, 12));
                    double LonSeconds = (BitConverter.ToUInt32(imageProperties.GetPropertyItem(4).Value, 16)) / (BitConverter.ToUInt32(imageProperties.GetPropertyItem(4).Value, 20));
                    longitude = LonDegrees + LonMinutes / 60 + LonSeconds / 3600;
                    Console.WriteLine(longitude);//longitude

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Oh ich sehe gerade, dass ihr auch bereits geantwortet habt. Naja hat nicht so schnell geladen... holzleitungen auf dem Dorf 😁

Aber Danke dafür. Dann geht das ja schon in die richtige Richtung.
Und bei dem Pfad zeigt der ja aktuell nur: V0050006.JPG an.
Aber sollte eigentlich den kompletten Pfad: C:/Users/UserName/Desktop/Neuer Ordner/V0050006.JPG

Grüße 🙂

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Eine viel schönere Lösung:

var allMetadata = ImageMetadataReader.ReadMetadata(filePath);
                    var gpsInfo = allMetadata.OfType<GpsDirectory>().FirstOrDefault();

                    // Angaben in Grad, Bogenminuten und Bogensekunde
                    var latitude = gpsInfo?.GetDescription(GpsDirectory.TagLatitude);
                    var longitude = gpsInfo?.GetDescription(GpsDirectory.TagLongitude);
                    Console.WriteLine($"{latitude}  {longitude}");

                    // Angabe in Grad und Graddezimale
                    var gpsData = gpsInfo?.GetGeoLocation();
                    Console.WriteLine($"{gpsData?.Latitude}  {gpsData?.Longitude}");

Nochmals danke für eure ganze Hilfe.

Aber trotzdem bleibt die Frage mit dem Pfad noch offen ? 🤔
Also wie könnte ich den komplett anzeigen lassen ?
C:/Users/UserName/Desktop/Neuer Ordner/V0050006.JPG

Liebe Grüße

1.029 Beiträge seit 2010
vor 5 Jahren

Hi,

beim besten Willen - ich erkenne den Sinn deiner letzten Frage nicht. Du hast den FilePath doch schon - sonst hättest du erst gar keine Infos auslesen können.

a) Ich bezweifle, dass die von dir genutzte Bibliothek etwas anderes liefert außer den Namen
b) Es würde nicht einmal Sinn machen, wenn die Bibliothek das unterstützt

LG

G
74 Beiträge seit 2018
vor 5 Jahren

Du meinst aber jetzt nicht den Serverpath ?

16.806 Beiträge seit 2008
vor 5 Jahren

Spielt hier wenig Rolle in dem Kontext.
Der Pfad ist vorhanden; er nutzt ihn ja aktiv.

Wenn er einen anderen meint, dann muss er sich entsprechend genauer ausdrücken.

1
124 Beiträge seit 2012
vor 5 Jahren

Meint er eventuell:


FileInfo fileinfo = new FileInfo(path);
Console.WriteLine(fileinfo.FullName);

16.806 Beiträge seit 2008
vor 5 Jahren

Dazu braucht man kein globiges FileInfo Objekt, was extrem langsam ist.
Da reicht auch direkt Path.GetFullPath - aber da er zwar die Beiträge noch liest aber nicht mehr antwortet.... alles Glaskugelraten.

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Hey sorry Leute das ich nicht geantwortet habe...aber das Glaskugelraten war erfolgreich : D

GENAU das habe ich gesucht.
Perfekt und Vielen Dank.

Das ganze benötige ich nämlich, da ich nun gerne auf einen ganzen Ordner zugreifen will und nicht nur auf ein Bild. Also von ganz vielen Bilder die jeweiligen MetaDaten angezeigt bekommen.
z.B C:/Hauptordner beinhaltet noch mehrere Unterordner in denen sich dann auch wieder Bilder befinden. Daher würde ich gerne zu jedem Bild auch den Pfad angezeigt bekommen, sodass ich sehe dass das eine Bild in C:/Hauptordner/Ordner1 und das andere z.B. in C:/Hauptordner/Ordner2/Ordner2.1 sich befindet.

Allerdings bereitet mir dieser ,,dynamische" Zugriff arge Probleme.
Ich bin auf GitHub auf folgende Möglichkeit gestoßen: PackageConfigReader

Ich habe die Projekte Finder.cs; NuGetPackage.cs; package.cs in mein Programm über den Explorer eingebunden.

So nun verstehe ich einfach nicht, was ich tun muss um den Code richtig einzubinden.
Wo gebe ich denn nun den gewünschten Pfad an und was muss ich tun damit mir die gewünschten Metadaten und zusätzlich jeder Pfad zum Bild angezeigt werden ?
Der Methode muss ja der Pfad übergeben werden und in einer foreach Schleife würde ich dann meine Print Methode aufrufen... 🤔

private static void Main(string[] args)
        {

          List<FileInfo> Search(string searchPath)
            {
                DirectoryInfo di = new DirectoryInfo(searchPath);

                string searchPattern = "packages.config";

                ICollection<FileInfo> matchingFileInfos = di.GetFiles(searchPattern, SearchOption.AllDirectories)
                    .Select(x => x)
                    .ToList();
                return matchingFileInfos.ToList();
            }

            var startPath = args[0];

            var finder = new Finder();
            var packageFiles = finder.Search(startPath);
            var packages = finder.GetPackages(packageFiles);

            var orderedPackages = packages.OrderByDescending(x => x.Occurrences);

            foreach (var package in orderedPackages)
            {
                Console.WriteLine($"{package.Name}, {package.Occurrences}");
            }

Vielleicht hat jemand von euch ja eine Hilfestellung für mich parat ?

Liebe Grüße

1.029 Beiträge seit 2010
vor 5 Jahren

Hi,

du solltest zumindest selbst mal versuchen zu verstehen was du dir da zusammenkopierst - in der Form hat das nämlich mit entwickeln nix zu tun.

a) Finder.cs brauchst du nicht
b) NugetPackage.cs brauchst du nicht
c) pacakge.cs brauchst du nicht

d) Schau dir doch bitte mal auf der MSDN die Methode "DirectoryInfo.GetFiles"-Methode an und bau dir eine für dich passende Suchfunktion. (Den Link poste ich jetzt hier absichtlich nicht)

LG

16.806 Beiträge seit 2008
vor 5 Jahren

Stehe da Taipi absolut bei.

Und in einem Forum sollte man immer genau beschreiben, was man vor hat.
Ein potentieller Helfer kann nicht hellsehen. Du stiehlst den Leuten damit nur Zeit (und Nerven) und kommst selbst auch viel schleppender (wenn überhaupt) an eine Lösung.
Bring einfach auf den Punkt, was Du willst - dann kann man auch helfen.

PS: Directory.EnumerateFiles ist absolut zu bevorzugen.
Im Rahmen von meinem QuickIO Projekt hab ich Vergleiche gezogen und die statische Methode EnumerateFiles ist ca. 50% schneller als GetFiles.
Kann man sich also generell angewöhnen.

E
easy867 Themenstarter:in
16 Beiträge seit 2018
vor 5 Jahren

Da habt ihr natürlich Recht.
Klappt auch schon jetzt ganz gut.

Die ganzen erfassten Daten möchte ich nun in Excel exportieren.

Beispiel:


foreach (var fi in di.GetFiles("*", SearchOption.AllDirectories))
{var latitude = gpsInfo?.GetDescription(GpsDirectory.TagLatitude);}
:
:
using (ExcelPackage excel = new ExcelPackage())
{ worksheet.Cells["A2"].Value = latitude;}

Problem: So wird ja nur der letzte Wert von latitude in Excel exportiert, da der Aufruf ja erst nach Beendigung der Schleife erfolgt.
Das ganze in einem Array abzuspeichern ist ja auch nicht so schön oder ?
Zudem muss ich ja auch irgendwie den ,,Cells[A2]" Bereich definieren, sodass der immer eine neue Zeile generiert also quasi inkrementiert wird. 🤔

Vielleicht hat dafür ja jemand eine Idee, wie die einzelnen Daten am besten für den Export zusammengefasst werden können und die Zellen bestimmt werden können.

Liebe Grüße 😜

16.806 Beiträge seit 2008
vor 5 Jahren

Bitte mach kein Endlosthread aus diesem Thema.
[Hinweis] Wie poste ich richtig?

Wenn Du ein Problem mit Excel hast, dann mach bitte dafür ein Thema auf.
Schau Dir aber zuerst Open XML an - denn damit arbeitet Excel.

Thema geschlossen