Unterschiedliche Anzahl von Exif tags beim Auslesen unter Verwendung von python modul und cli exiftool

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
klooney
User
Beiträge: 13
Registriert: Freitag 3. Februar 2023, 17:56

Ich bin dabei mein erstes python3 Programm unter Linux zu schreiben. Also Vorsicht: Anfängerfrage. Dem Programm wird als Parameter die Datei übergeben und soll einfach das jpg anzeigen als auch in einer Tabelle daneben die Exif-tags.
Wenn ich die Exif-tags aus eins meiner selbst aufgenommenen Fotos (jpg) über das command line tool exiftool auslese und zähle, komme ich auf 220 tags. Die ausgegebene Menge an tags und dessen keys/values von exiftool sind zweifelsfrei richtig. Wenn ich mit python die tags auslese fehlen jedoch eine Menge, es sind nur 50 tags.

Code: Alles auswählen

...
import exifread
f = open(sys.argv[1], 'rb')
tags = exifread.process_file(f)
print('Tag-Länge: ', len(tags)) 
---
output:
50

Ich habe mal als Alternative das Modul pyexiv2 verwendet. Da erhalte ich 60 tags, aber auch nicht 220. Was mache ich falsch - oder habe ich dabei einen Denkfehler?
Benutzeravatar
sparrow
User
Beiträge: 4233
Registriert: Freitag 17. April 2009, 10:28

Ich weiß nicht, wie hoch die Wahrscheinlichkeit ist, dass sich hier jemand so tief mit den Bibliotheken beschäftigt hat.
Vielleicht solltest du einmal schauen, welche Tags fehlen um dem ganzen auf die Spur zu kommen.
klooney
User
Beiträge: 13
Registriert: Freitag 3. Februar 2023, 17:56

Es gibt im Netz so viele Code-Schnipsel zum Auslesen der exif-tags. Allerdings habe ich bisher noch keins gefunden, das funktioniert. Entweder sind die Bibliotheken nicht auf python3 angepasst und verursachen Fehler oder sie lesen nur ein subset der exif-tags aus wie oben beschrieben. Ich könnte ja auch exiftool als subprozess starten. Da müsste dann aber auch auf anderen Rechnern das Programm exiftool installiert sein. Also auch keine gute Lösung.
Benutzeravatar
sparrow
User
Beiträge: 4233
Registriert: Freitag 17. April 2009, 10:28

Nochmal: Welcher spezielle Tag fehlt dir denn, wenn du das wie in deinem ersten Post aufrufst?
klooney
User
Beiträge: 13
Registriert: Freitag 3. Februar 2023, 17:56

sparrow hat geschrieben: Freitag 17. Februar 2023, 20:32 Nochmal: Welcher spezielle Tag fehlt dir denn, wenn du das wie in deinem ersten Post aufrufst?
Ich hatte es in dem Eingangstext schon kurz beschrieben, dass ich die Exif-tags in einer Tabelle angezeigt bekommen möchte. Und damit meine ich alle tags. Welche denn nun fehlen? Es ist die Differenz von den 220 zu 50, also genau 170 tags. Ein automatischer Abgleich der Fehlenden tags ist (für mich) erstmal nicht so einfach, da der Output der Keys im Key/Value-Tupel von exiftool und der verwendeten Python-Bibliothek unterschiedlich ist. Bei der letztgenannten Variante sind Präfixe enthalten.
nezzcarth
User
Beiträge: 1645
Registriert: Samstag 16. April 2011, 12:47

Exiftool zeigt – trotz des Exif im Namen – nicht nur Exif-Tags an, sondern diverse andere Formate wie XMP, IPTC, … ; es ist eher ein generisches Tool zum Anzeigen eingebetteter Metadaten und gar nicht auf Bilder und Exif beschränkt. Ein Blick in die Manpage verrät, was das sonst noch so auslesen kann. Um also zu sagen, was da genau fehlt, musst du einen detaillierten Vergleich zwischen der Ausgabe von Exiftool und dem der Python-Bibliothek, die ja nur Exif kann, anstellen. Es ist fraglich, wie viele von den 170 fehlenden Tags überhaupt Exif-Tags sind.
Benutzeravatar
noisefloor
User
Beiträge: 3879
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

also es gibt schon sauviele EXIF Tags. Die von EXIF Tool unterstützten sind hier zu finden: https://exiftool.org/TagNames/EXIF.html.

Was dann zu der Frage führt: braucht man immer alles? Es kann also schon gut zu, dass andere Bibliotheken nur ein Subset unterstützen, ggf. das, von dem der Programmierer ausgeht, dass man es landläufig braucht. Also sowas wie Aufnahmedatum, Geolocation, Blende, Belichtungszeit usw.

Wenn du wirklich die volle Bandbreite brauchst, dann macht es IMHO schon Sinn, spezialisierte Tools wie exiftool einzubinden bzw. erst Mal zu schauen, ob es ggf. einen Python-Wrapper dafür gibt.

Bei 200+ Tags muss man sich auch IMHO Gedanken über die Strukturierung machen. Klar ist für Python ein Dict mit ein paar hunders Einträgen überhaupt kein Problem, aber vielleicht will man die Tags noch in logische / funktionelle Gruppen gruppieren.

Gruß, noisefloor
Benutzeravatar
sparrow
User
Beiträge: 4233
Registriert: Freitag 17. April 2009, 10:28

@klooney: Ich denke du verstehst nicht, was ich meine. Du bewertest irgendwelche Daten nach ihrer Quantität ohne ihren Inhalt zu hinterfragen.
Noch ein drittes Mal, vielleicht hilft die Langform:

Such dir Tags (<- da steht nicht _alle Tags_) die von dem einen Tool angezeigt werden und von dem anderen nicht.
Finde heraus welche Bedeutung und Spezifikationen diese Tags haben.

Mit den daraus gewonnen Erkentnissen kannst du dann auf Lösungssuche gehen.
Ein paar mögliche Ursachen wurden ja hier schon genannt. Sind es vielleicht gar keine EXIF-Tags?
Oder gehören sie zu einem bestimmten Subset?

Zu sagen "da fehlen x" ist das Resultat. Du musst herausfinden _warum_ das so ist oder sein könnte.
klooney
User
Beiträge: 13
Registriert: Freitag 3. Februar 2023, 17:56

Ja, danke soweit für die Anregungen hier. Offensichtlich hat sich noch niemand, der sich etwas besser auskennt als ich, mit diesem Dilemma auseinandergesetzt. Scheinbar auch nicht im Google-durchsuchbaren Internet.
Wie gesagt, ich bin ein Python Anfänger. Aber um das Thema und den thread mal zum Ende zu bringen, noch ein paar abschließende Kommentare.
@nezzcarth: das Programm exiftool kann auch andere tags als Exif lesen, das ist richtig. Allerdings werden standardmäßig nur die exif-tags gelesen, die @noisefloor richtig mit der URL verlinkt hat. Das ganze Set beinhaltet lt. Dokumentation ca. 500 exif tags, die natürlich nicht alle von den Kameras genutzt werden. Meine Panasonic nutzt aber immerhin schon 220 davon. Auf ein Python Wrapper für exiftool würde ich gern verzichten, da es das Tool auf dem Rechner voraussetzt. Ich möchte das Python-Programm später auch auf einem Windows Rechner in Betrieb nehmen und später mit einigen anderen Funktionen ggf. anderen Interessierten zur Verfügung stellen. Weitere Abhängigkeiten wären daher von Nachteil.
@sparrow: ich verstehe schon, was du schreibst. Es ist nicht nett, mich wiederholt als etwas begriffsstutzig darzustellen. Die einfache Anforderung des Programms hatte ich eingangs kurz beschrieben. Ich will die tags nicht bewerten oder gruppieren, sondern alle vorhandenen nur (in alpabetischer Reihenfolge) tabellarisch darstellen. Ob das nun für den einen oder anderen einen Sinn ergibt oder auch nicht. Um der Ursache auf den Grund zu gehen, warum die oben erwähnten Bibliotheken nur einen Teil der tags auslesen fehlt mir schlichtweg das technische Verständnis :idea: .
Benutzeravatar
sparrow
User
Beiträge: 4233
Registriert: Freitag 17. April 2009, 10:28

@klooney: Wo stelle ich dich denn bitte als begriffstutzig hin? Und wo habe ich denn gesagt, dass ich davon ausgehe, dass du irgendwas bewerten oder gruppieren sollst? Ich habe dir lediglich gesagt, wie du deinem Problem auf die Spur kommen kannst. Das hat nichts mit dem zu tun, was du am Ende damit machen willst.
Und ja, manchmal muss man (technisches) Verständis aufbringen oder erarbeiten um Probleme zu verstehen und zu lösen.
Aber wenn die einzige Lösung für dich ist, dass du ohne jeglichen Aufwand das Ergebnis von exiftool bekommst, ist das naheliegenste von nezzcarth bereits genannt: Nimm exiftool.
nezzcarth
User
Beiträge: 1645
Registriert: Samstag 16. April 2011, 12:47

klooney hat geschrieben: Samstag 18. Februar 2023, 15:39 @nezzcarth: das Programm exiftool kann auch andere tags als Exif lesen, das ist richtig. Allerdings werden standardmäßig nur die exif-tags gelesen, die @noisefloor richtig mit der URL verlinkt hat.
Das ist nach meinem Kenntnisstand nicht korrekt. Ich habe es gerade extra noch einmal ausprobiert und "exiftool <bildname.jpg>" ohne weitere Parameter gibt mir z.B. auch XMP-Tags aus, die Darktable gesetzt hat. Dies habe ich auch noch einmal mit 'exifv2 -p a <bildname.jpg>' gegen geprüft.
klooney hat geschrieben: Samstag 18. Februar 2023, 15:39 Um der Ursache auf den Grund zu gehen, warum die oben erwähnten Bibliotheken nur einen Teil der tags auslesen fehlt mir schlichtweg das technische Verständnis :idea:
Die Ursache ist im Prinzip relativ einfach: Die Tags werden nicht "einfach so" unterstützt, sondern müssen explizit berücksichtigt werden. ExifTool ist hier, würde ich schon sagen, schon ganz vorne mit dabei, wenn nicht sogar die unangefochtene Spitze, da es eine Vielfalt an Formaten, Hersteller-spezifische Erweiterungen usw. berücksichtigt. Da ist es für andere Bibliotheken einfach extrem schwer, mitzuhalten.

Du hattest in deinem Code-Beispiel exifread verwendet. Die entsprechenden Code-Passagen, aus denen hervorgeht, was die Software unterstützt, sind hier zu sehen
https://github.com/ianare/exif-py/tree/ ... fread/tags
Hier sieht man, dass einerseits gängige Exif-Tags einschl. GPS (exif.py) unterstüzt werden, sowie 7 herstellerspezifische Erweiterungen.

ExifTool ist ein Wrapper um die Perl-Bibliothek Image:ExifTool. Wenn man sich auch hier die entsprechenden Code-Teile dazu ansieht, sieht man sofort, dass das einfach mehrere Größenordnungen über dem liegt, was die Python-Bibliothek unterstützt. Selbst wenn man berücksichtigt, dass nicht nur Exif sondern noch mehr drin steckt, ist einfach die Menge ungleich höher. ExifTool ist einfach sehr komplex (allein schon die Spezifika einzelner Hersteller herauszubekommen stelle ich mir als große Herausforderung vor) und ich bezweifle, dass es ein zweites Tool/eine zweite Bibliothek gibt, das/die die Ergebnisse von ExifTool exakt reproduziert. Um mit Python also dasselbe Resultat zu erzielen wie mit ExifTool, müsstest du das alles nach Python übersetzen. Das ist vermutlich keine Anfänger-Aufgabe.
nezzcarth
User
Beiträge: 1645
Registriert: Samstag 16. April 2011, 12:47

Nachtrag: Ich hatte vergessen, den Perl-Code zu verlinken: https://metacpan.org/release/EXIFTOOL/I ... e/ExifTool
Zusammengefasst: Das Problem ist weniger, dass die Python-Bibliotheken so wenig anzeigen, sonder mehr, dass ExifTool so viel anzeigt und dadurch falsche Erwartungen weckt.
Benutzeravatar
Whitie
User
Beiträge: 216
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

Es gibt für Python PyExifTool und hier gibt es ExifTool als einzelnes Binary für Windows. Für den privaten Gebrauch spricht nichts dagegen, das Binary mit deinem Programm mitzugeben. Du prüfst beim Programmstart, ob ExifTool im Pfad ist und ermittelst die Plattform. Auf Windows greifst du dann ggf. auf das Binary zurück.

Viele Grüße
Whitie
klooney
User
Beiträge: 13
Registriert: Freitag 3. Februar 2023, 17:56

Besten Dank noch einmal für die hilfreichen Kommentare. Das Thema scheint doch erstmal ziemlich einfach zu sein, wenn man sich mit exiftool der Sache nähert. Sobald man selbst hinein taucht, wird es komplizierter. PyExitTool habe ich tatsächlich ausprobiert. Es kommt dem Output von exiftool schon ziemlich nahe. Allerdings gibt es Ausgaben, die nicht automatisch konvertiert werden und für die ich kein Parameter bzw. Schalter finde, z.B:

Code: Alles auswählen

[b]Tool                           Key                                Value[/b]
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Output PyExitTool                  Exposure Mode                     [EXIF]          Exposure Mode                   : 1
Output exiftool                    Exposure Mode                    : Manual
Hier sieht man, dass exiftool den Wert (value) automatisch in ein lesbares Format konvertiert. PyExitTool liefert nur den numerischen Wert und ordnet zudem jede Zeile in drei Spalten an (Gruppe, Key, Value).
Benutzeravatar
noisefloor
User
Beiträge: 3879
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ich glaube, du stehst dir selber im Weg. Du bist total fokussiert darauf, dass ein existierendes Python-Modul geben muss, was 100% identisch das ausgibt, was ExifTool ausgibt. Könnte schwierig werden. Also entweder nutzt du ExifTool via `subprocess` und bastelst dir in Python was, was die Ausgabe korrekt parsen kann. Oder du liest dich tiefer in PyExifTool ein. Was das Programm ausgibt ist doch sekundär - wichtig ist, was die Methoden an Werten zurückgegeben und wie du es weiter verwenden kannst. Wie die Datenrepräsentation mittels `print` ist sekundär. Oder du überdenkst deine Pläne komplette und schwenkst auf eine andere Python-Bibliothek für Exif um.

Gruß, noisefloor
klooney
User
Beiträge: 13
Registriert: Freitag 3. Februar 2023, 17:56

Na geht doch, einigermaßen jedenfalls. Auch wenn ich mir selber im Weg stehe und nichts verstehe, so dass einige Kommentare noch und nochmals wiederholt werden. Ich nutze nun den wrapper, um exiftool auszuführen. Wenn auch noch so einiges im Code fehlt, wie z.B. mit Exception umgegangen wird, der Kern des Skripts tut, was er soll (bis auf eine Sache) und besteht nun aus dem folgendem Code:

Code: Alles auswählen

	...
	import exiftool
	...
	self.ui.tableWidget.setColumnCount(3)
        self.ui.tableWidget.setHorizontalHeaderLabels(["Group", "Key", "Value"])
        i = 0

        # Read Metadata
        with exiftool.ExifTool() as et:
            metadata = et.execute("-G", str(sys.argv[1]))

        single_rows = metadata.split('\n')
        self.ui.tableWidget.setRowCount(len(single_rows))
        for single_row in single_rows:
            if single_row[0:14].strip(': ][)') != "":
            	print (single_row)
                self.ui.tableWidget.setItem(i, 0, QTableWidgetItem(single_row[0:14].strip(': ][)')))
                self.ui.tableWidget.setItem(i, 1, QTableWidgetItem(single_row[12:49].strip('] :')))
                self.ui.tableWidget.setItem(i, 2, QTableWidgetItem(single_row[50:200].strip('] :')))
            else:
                self.ui.tableWidget.setRowCount(len(single_rows) - 1)
            i += 1
Anschließend sortiere ich noch die Tabelle und das Fenster wird angepasst usw. Ich frage mich jedoch, warum die dritte Spalte der Tabelle in der GUI nicht mit der Spaltenüberschrift "Value" versehen wird.(?) Die ersten beiden Spalten sind mit Group und Key richtig gesetzt. Dabei setzte ich explizit die Header mit

Code: Alles auswählen

self.ui.tableWidget.setColumnCount(3)
self.ui.tableWidget.setHorizontalHeaderLabels(["Group", "Key", "Value"])
Wenn ich das Ganze mit print (single_row) ausgebe, sieht das auf der console so aus (Auszug aus den 220 Zeilen der Metadaten)

Code: Alles auswählen

[ExifTool]      ExifTool Version Number         : 12.42
[File]          File Name                       : P1035051.jpg
[File]          Directory                       : /home/kirk/Bilder/Panasonic
[File]          File Size                       : 1266681
[File]          File Modification Date/Time     : 2022:10:21 12:45:16+02:00
[File]          File Access Date/Time           : 2023:02:20 19:37:09+01:00
[File]          File Inode Change Date/Time     : 2022:11:24 11:49:35+01:00
[File]          File Permissions                : 100644
[File]          File Type                       : JPEG
[File]          File Type Extension             : JPG
[File]          MIME Type                       : image/jpeg
[File]          Exif Byte Order                 : II
[File]          Image Width                     : 2148
[File]          Image Height                    : 1442
[File]          Encoding Process                : 0
[File]          Bits Per Sample                 : 8
[File]          Color Components                : 3
[File]          Y Cb Cr Sub Sampling            : 1 1
[JFIF]          JFIF Version                    : 1 1
[EXIF]          Image Description               : 
[EXIF]          Make                            : Panasonic
[EXIF]          Camera Model Name               : DC-S1R
[EXIF]          Orientation                     : 1
[EXIF]          X Resolution                    : 300
[EXIF]          Y Resolution                    : 300
[EXIF]          Resolution Unit                 : 2
[EXIF]          Software                        : darktable 4.1.0+570~g086d7b2b8
[EXIF]          Modify Date                     : 2022:10:21 12:45:16
Antworten