Daten auslesen

Mit Listing 8 steht eine generische Schnittstelle zum Rotieren von Bildern bereit, die beliebige Drehwinkel ermöglicht. Im Alltag reduziert sich das häufig auf die Notwendigkeit, Bilder korrekt im Quer- oder Hochformat anzuzeigen. Viele Programme werten dazu bereits Zusatzinformationen in den Bildern aus und stellen das Bild entsprechend gedreht dar. LinuxUser stellte dazu bereits die Möglichkeiten von Geeqie (Abbildung 3) vor [13].

Abbildung 3: Gqview/Geeqie stellt das Bild und dessen Exif-Daten dar.

Diese Zusatzinformationen zu den Aufnahmen stehen oft im Exchangeable Image File Format (Exif, [14]) bereit und beinhalten beispielsweise die Auflösung des Bildes, den Kamerahersteller und das Modell, den Farbraum, die genutzten Filter und Objektive sowie die Orientierung für Hoch- oder Querformat [15]. Dabei unterstützen die Kameras nur die Formate JPEG, TIFF (Rev. 6) und RIFF WAV, die Formate PNG und GIF bleiben bislang außen vor.

Viele Beispiele im Netz zeigen den erfolgreichen Zugriff auf die Exif-Daten mit dem speziellen PIL-Modul ExifTags. Diese Information scheint für aktuelle PIL-Versionen veraltet zu sein, denn das Auslesen gelang damit nicht. Die Alternative Pyexiv2 [16] lieferte hingegen Ergebnisse. Das Modul stellt eine Schnittstelle für die C++-Bibliothek Exiv2 bereit.

Als vollständiges Beispiel zum Auslesen der Exif-Daten dient Listing 9: Nach dem Laden des Bildes (Zeile 14) erfolgt das Lesen der Exif-Daten mit der Methode readMetadata (Zeile 15). Eine Liste der gefundenen Metatags liefert die Methode exifKeys (Zeile 16). In Zeile 18 gibt das Skript die Liste zusammen mit den gespeicherten Metadaten aus. Es akzeptiert als einzigen Parameter eine Datei im JPG- oder TIFF-Format, beispielsweise aufgerufen wie in Listing 10.

Listing 9

# exif.py
# -*- coding: utf-8 -*-
# Module System und Pyexiv2 laden
import sys
import pyexiv2
kommandozeile = sys.argv[1:]
dateiname = kommandozeile[0]
print ("Datei: %s" % dateiname)
try:
  bild = pyexiv2.Image(dateiname)
  bild.readMetadata()
  info = bild.exifKeys()
  for key in info:
    print ("%s: %s" % (key, bild[key]))
except IOError:
  print ("Fehler: kann %s nicht bearbeiten" % dateiname)

Listing 10

$ python exif.py IMG_0284.JPG
Datei: IMG_0284.JPG
Exif.Image.Make: Canon
Exif.Image.Model: Canon PowerShot A470
Exif.Image.Orientation: 1
Exif.Image.DateTime: 2008-09-14 11:05:50
Exif.Photo.PixelXDimension: 2048
Exif.Photo.PixelYDimension: 1536
...

Die Liste und Werte der Exif-Tags variieren und hängen von der Kamera selbst, deren Firmware und den Kamera-Einstellungen ab (siehe dazu das Interview mit Phil Harvey [17], dem Entwickler von Exiftool).

Die Ausgabe in Listing 10 verrät, dass das Bild mit einer Canon Powershot A470 am 14. September 2008 kurz nach 11 Uhr aufgenommen wurde (genauer: die Kamera hat diesen Zeitstempel eingetragen). Das Bild hat eine Breite von 2048 Pixel und eine Höhe von 1536 Pixel.

Die Zeile Exif.Image.Orientation mit dem Wert 1 besagt, dass die Aufnahme im Querformat vorliegt. Gemäß [18] sind auch die Werte in Tabelle "Ausrichtungsoptionen" gültig. Eine Kamera ermittelt die Ausrichtung über einen Lagesensor, mittels dessen sie erkennt, ob Sie gerade im Hoch- oder Querformat aufnehmen. Demgemäß setzt sie den entsprechenden Wert in den Exif-Daten. Verfügt das Aufnahmegerät über keinen solchen Sensor, trägt es bei allen Aufnahmen eine 1 ein, geht also vom Querformat aus.

Ausrichtungsoptionen

Option Bedeutung Winkel
1 Querformat, Nullpunkt oben links Drehen um 0 Grad
3 Querformat, Nullpunkt unten rechts Drehen um 180 Grad
6 Hochformat, Nullpunkt oben rechts Drehen um 90 Grad
8 Hochformat, Nullpunkt unten links Drehen um 270 Grad

Nach Exif-Daten drehen

Als letztes Beispiel dient ein Skript, welches das Bild so dreht, wie es sich der Fotograf bei der Aufnahme gedacht hat. Die Grundlage dazu liefern die Exif-Daten, die den notwendigen Drehwinkel verraten. Dazu kombiniert der Code in Listing 11 Funktionen aus PIL und Pyexiv2.

Nach dem Vorspann (Zeile 1 bis 8) und dem Auswerten der Parameter (Zeile 9 bis 13) liest das Skript die Exif-Daten aus der Bilddatei aus (Zeile 16 bis 19).Interessant ist der Eintrag Exif.Image.Orientation, dessen Wert in der Variable ausrichtung landet (Zeile 19). Zeile 21 enthält eine Liste mit Einträgen, die jedem Wert der Ausrichtung den entsprechenden Drehwinkel zuordnet. Dabei fungiert der Wert der Ausrichtung als Index in der Liste.

Falls die Ausrichtung einen Wert größer "1" beinhaltet, gilt es, das Bild entsprechend zu drehen. In den Zeilen 27 bis 29 erledigt die PIL-Methode rotate das Rotieren des Bildes. Dabei gehen im neuen Bild zunächst die Exif-Daten verloren. Deswegen überträgt das Skript diese in den Zeilen 31 bis 45 aus dem alten Bild ins neue. Dazu kopiert es die Werte des Ursprungsbildes zunächst vollständig in die Datenstruktur des neuen Bildes (Zeilen 33 bis 38).

Liegt ein Bild im Hochformat vor, bedürfen alle achsenbezogenen Werte einer Korrektur, also Höhe und Breite des Bildes sowie die Auflösung und Ausrichtung. Schließlich speichert das Skript das Ergebnis in Zeile 45 in der neuen Datei.

Listing 11

# exif2.py
# -*- coding: utf-8 -*-
# Module System, PIL und Pyexiv2 laden
import sys
import pyexiv2
import Image
kommandozeile = sys.argv[1:]
dateiname = kommandozeile[0]
ausgabedatei = kommandozeile[1]
print ("Datei: %s" % dateiname)
try:
  bild = pyexiv2.Image(dateiname)
  bild.readMetadata()
  info = bild.exifKeys()
  ausrichtung = bild['Exif.Image.Orientation']
  zuordnung = {1: 0.0, 3: 180.0, 6: 90.0, 8: 270.0}
  drehwinkel = zuordnung[ausrichtung]
  print ("Ausrichtung: %i" % ausrichtung)
  print ("Drehwinkel: %f Grad" % drehwinkel)
  if ausrichtung > 1:
    neuesbild = Image.open(dateiname)
    neuesbild = neuesbild.rotate(drehwinkel)
    neuesbild.save(ausgabedatei)
    neuesbild = pyexiv2.Image(ausgabedatei)
    neuesbild.readMetadata()
    for key in info:
      try:
        neuesbild[key] = bild[key]
      except:
        print ("Konvertierungsfehler bei Eintrag %s" % key)
    neuesbild['Exif.Image.Orientation'] = 1
    if ausrichtung > 5:
      neuesbild['Exif.Image.XResolution'] = bild['Exif.Image.YResolution']
      neuesbild['Exif.Image.YResolution'] = bild['Exif.Image.XResolution']
      neuesbild['Exif.Photo.PixelXDimension'] = bild['Exif.Photo.PixelYDimension']
      neuesbild['Exif.Photo.PixelYDimension'] = bild['Exif.Photo.PixelXDimension']
    neuesbild.writeMetadata()
    print ("Ausgabedatei: %s" % ausgabedatei)
except IOError:
  print ("Fehler: kann %s nicht bearbeiten" % dateiname)

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 

Ähnliche Artikel

Kommentare

Infos zur Publikation

LU 11/2014: VIDEOS BEARBEITEN

Digitale Ausgabe: Preis € 4,95
(inkl. 19% MwSt.)

Mit der Zeitschrift LinuxUser sind Sie als Power-User, Shell-Guru oder Administrator im kleinen Unternehmen monatlich auf dem aktuelle Stand in Sachen Linux und Open Source.

Sie sind sich nicht sicher, ob die Themen Ihnen liegen? Im Probeabo erhalten Sie drei Ausgaben zum reduzierten Preis. Einzelhefte, Abonnements sowie digitale Ausgaben erwerben Sie ganz einfach in unserem Online-Shop.

NEU: DIGITALE AUSGABEN FÜR TABLET & SMARTPHONE

HINWEIS ZU PAYPAL: Die Zahlung ist auch ohne eigenes Paypal-Konto ganz einfach per Kreditkarte oder Lastschrift möglich!       

Tipp der Woche

Schnell Multi-Boot-Medien mit MultiCD erstellen
Schnell Multi-Boot-Medien mit MultiCD erstellen
Tim Schürmann, 24.06.2014 12:40, 0 Kommentare

Wer mehrere nützliche Live-Systeme auf eine DVD brennen möchte, kommt mit den Startmedienerstellern der Distributionen nicht besonders weit: Diese ...

Aktuelle Fragen

Artikelsuche
Erwin Ruitenberg, 09.10.2014 07:51, 1 Antworten
Ich habe seit einige Jahre ein Dugisub LinuxUser. Dann weiß ich das irgendwann ein bestimmtes Art...
Windows 8 startet nur mit externer Festplatte
Anne La, 10.09.2014 17:25, 6 Antworten
Hallo Leute, also, ich bin auf folgendes Problem gestoßen: Ich habe Ubuntu 14.04 auf meiner...
Videoüberwachung mit Zoneminder
Heinz Becker, 10.08.2014 17:57, 0 Antworten
Hallo, ich habe den ZONEMINDER erfolgreich installiert. Das Bild erscheint jedoch nicht,...
internes Wlan und USB-Wlan-Srick
Gerhard Blobner, 04.08.2014 15:20, 2 Antworten
Hallo Linux-Forum: ich bin ein neuer Linux-User (ca. 25 Jahre Windows) und bin von WIN 8 auf Mint...
Server antwortet mit falschem Namen
oin notna, 21.07.2014 19:13, 1 Antworten
Hallo liebe Community, Ich habe mit Apache einen Server aufgesetzt. Soweit, so gut. Im Heimnet...