Hallo Leute,
Ich verwende den Metadaten-Extraktor ähnlich wie in diesem Beispiel: Beispiel MetadataExtractor
um viele Metadaten von Bildern aus verschiedenen Ordnern auszulesen.
Jedoch habe ich ein aktuelles Problem:
Sobald anderen Datentypen als .jpg in irgendeinem Ordner abliegen, funktioniert es nicht mehr.
z.B. .txt
Ist es also möglich, alle unterschiedlichen Datentypen zu ignorieren?
Und wenn ja, wie ?
Hoffe auf etwas Hilfe.
Liebe Grüße
Hey Leute,
ich möchte mir gerne das Datum anzeigen lassen, an dem ein Foto gemacht wurde und zwar im folgenden Format: 08.02.2015 12:14:23
Folgende Idee:
Globals.date = fi.CreationTime; //zeigt jedoch das falsche Datum an (wahrscheinlich Erstellung des Skriptes) aber richtige Darstellung
Globals.date = (Image?.GetDescription(306))// richtige Datum aber falsche Darstellung 08:02:2015 12:14:23
//Versuche zur Formatierung
Globals.date.ToString("d",CultureInfo.CreateSpecificCulture("de-DE"))
Globals.date= String.Format("{0:d/M/yyyy HH:mm:ss}", Globals.date = (Image?.GetDescription(306)))
Die Formatierung misslingt jedoch.
Jemand eine Idee wie sich das lösen lässt ?
Liebe Grüße
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 😜
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
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
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 🙂
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
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
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
}
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 😁
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. 🤔
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
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
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.
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
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.