Sidebar
ein-/ausblenden

EXIF-Daten mit PHP aus Bildern auslesen

Plugin für WordPress SEO

Anzeige

Exif
Die digitale Welt greift weiter um sich. Dabei spielt die digitale Photographie eine große Rolle und immer mehr Nutzer präsentieren ihre Bilder im Netz. Für diese Form gibt es eine ganze Reihe von Lösungen. Immer mehr Software und Kameras unterstützen das EXIF-Format und schreiben eine ganze Reihe von Information in die Bilder.

Nur die wenigsten Möglichkeiten unterstützen das Auslesen und Darstellen der EXIF-Header Daten eines Bildes. Aber gerade beim Präsentieren von Bildern sind diese Information oft sinnvoll und nützlich, ob für die eigenen Zwecke oder um dem geneigten Lesern die Einstellungen der Kamera nahe zu legen und damit eventuell ähnliche Ergebnisse zu erreichen. Verwendung findet diese Funktion im PhotoBlog-Theme, welches ich auch selbst nutze.

PHP stellt seit Version 4.2.0 eine eigene Funktion bereit, die die EXIF-header-Daten auslesen kann. Ich habe die Möglichkeit genutzt und in eine eigene Funktion implementiert. Die Werte der Funktion exif_read_data werden in einem Array abgelegt und entsprechen nicht den üblichen Leseformen von Photographieinteressenten. Dazu muss ein wenig mehr machen. Einziger Nachteil, die Funktion kann lediglich JPG und TIFF auslesen. Will man das im Vorfeld sicher stellen, dann hilft die Funktion exif_imagetype.

Damit man das Rad nicht immer neu erfinden muss, kann die folgende Funktion gerne genutzt werden. Die Funktion liest nicht alle Werte aus - es gibt recht viele, und nicht alle hielt ich für relevant. Damit man aber mal einen Überblick über alle Inhalte bekommen kann, ist der folgende Syntax hilfreich.


$image = '/pfad/bild.jpg';
$exif = exif_read_data($image, 0 , true);

foreach ($exif as $key => $section) {
	foreach ($section as $name => $val) {
		echo "$key.$name: $val\n";
	}
}

function fb_read_write_exif_data($post_ID) {

	$image = '/pfad/bild.jpg';

	if ($image != '') {
		error_reporting(0);

		$exif = exif_read_data($image, 0 , true);

		if(isset($exif["EXIF"]["DateTimeOriginal"])) {
			$fbdateoriginal = str_replace(":","-",substr($exif["EXIF"]["DateTimeOriginal"], 0, 10));
			$fbtimeoriginal = substr($exif["EXIF"]["DateTimeOriginal"], 10);
			print __('Datum:', 'photoblogfb') . " {$fbdateoriginal}";
			print __(' · Uhrzeit:', 'photoblogfb') . " {$fbtimeoriginal}";
			print "\n";
		}

		if(isset($exif["EXIF"]["FNumber"])) {
			list($num, $den) = explode("/",$exif["EXIF"]["FNumber"]);
			$fbaperture  = "F/" . ($num/$den);
			print __('Blende:', 'photoblogfb') . " {$fbaperture}";;
		}

		if(isset($exif["EXIF"]["ExposureTime"])) {
			list($num, $den) = explode("/", $exif["EXIF"]["ExposureTime"]);
			if ($num > $den) {
				$fbexposure = "{$num}s";
				print __(' · Belichtungsdauer:', 'photoblogfb') . " {$fbexposure}";
			} else {
				$den = round($den/$num);
				$fbexposure = "1/{$den}s";
				print __(' · Belichtungsdauer:', 'photoblogfb') . " {$fbexposure}";
			}
		}

		if(isset($exif["EXIF"]["FocalLength"])) {
			list($num, $den) = explode("/", $exif["EXIF"]["FocalLength"]);
			$fbfocallength  = ($num/$den) . "mm";
			print __(' · Brennweite:', 'photoblogfb') . " {$fbfocallength}";
		}

		if(isset($exif["EXIF"]["FocalLengthIn35mmFilm"])) {
			$fbfbfocallength35 = $exif["EXIF"]["FocalLengthIn35mmFilm"];
			print __(', (KB-Format entsprechend:', 'photoblogfb') . " {$fbfbfocallength35}" . __('mm)');
		}

		print "\n";

		if ( isset($exif["EXIF"]["ISOSpeedRatings"]) ) {
			print __('ISO:', 'photoblogfb') . " {$exif["EXIF"]["ISOSpeedRatings"]}";
		}

		if (isset($exif["EXIF"]["WhiteBalance"]) ) {
			switch($exif["EXIF"]["WhiteBalance"]) {
				case 0:
					$fbwhitebalance = "Auto";
					break;
				case 1:
					$fbwhitebalance = "Daylight";
					break;
				case 2:
					$fbwhitebalance = "Fluorescent";
					break;
				case 3:
					$fbwhitebalance = "Incandescent";
					break;
				case 4:
					$fbwhitebalance = "Flash";
					break;
				case 9:
					$fbwhitebalance = "Fine Weather";
					break;
				case 10:
					$fbwhitebalance = "Cloudy";
					break;
				case 11:
					$fbwhitebalance = "Shade";
					break;
				default:
					$fbwhitebalance = '';
					break;
			}
			print __(' · Weißabgleich:', 'photoblogfb') . " {$fbwhitebalance}";
		}

		if (isset($exif["EXIF"]["Flash"]) ) {
			switch($exif["EXIF"]["Flash"]) {
				case 0:
					$fbexif_flash = 'Flash did not fire';
					break;
				case 1:
					$fbexif_flash = 'Flash fired';
					break;
				case 5:
					$fbexif_flash = 'Strobe return light not detected';
					break;
				case 7:
					$fbexif_flash = 'Strobe return light detected';
					break;
				case 9:
					$fbexif_flash = 'Flash fired, compulsory flash mode';
					break;
				case 13:
					$fbexif_flash = 'Flash fired, compulsory flash mode, return light not detected';
					break;
				case 15:
					$fbexif_flash = 'Flash fired, compulsory flash mode, return light detected';
					break;
				case 16:
					$fbexif_flash = 'Flash did not fire, compulsory flash mode';
					break;
				case 24:
					$fbexif_flash = 'Flash did not fire, auto mode';
					break;
				case 25:
					$fbexif_flash = 'Flash fired, auto mode';
					break;
				case 29:
					$fbexif_flash = 'Flash fired, auto mode, return light not detected';
					break;
				case 31:
					$fbexif_flash = 'Flash fired, auto mode, return light detected';
					break;
				case 32:
					$fbexif_flash = 'No flash function';
					break;
				case 65:
					$fbexif_flash = 'Flash fired, red-eye reduction mode';
					break;
				case 69:
					$fbexif_flash = 'Flash fired, red-eye reduction mode, return light not detected';
					break;
				case 71:
					$fbexif_flash = 'Flash fired, red-eye reduction mode, return light detected';
					break;
				case 73:
					$fbexif_flash = 'Flash fired, compulsory flash mode, red-eye reduction mode';
					break;
				case 77:
					$fbexif_flash = 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected';
					break;
				case 79:
					$fbexif_flash = 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected';
					break;
				case 89:
					$fbexif_flash = 'Flash fired, auto mode, red-eye reduction mode';
					break;
				case 93:
					$fbexif_flash = 'Flash fired, auto mode, return light not detected, red-eye reduction mode';
					break;
				case 95:
					$fbexif_flash = 'Flash fired, auto mode, return light detected, red-eye reduction mode';
					break;
				default:
					$fbexif_flash = '';
					break;
				}
				print __(' · Blitz:', 'photoblogfb') . " {$fbexif_flash}";
		}

		/**
		if(isset($exif["EXIF"]["Flash"])) {
			$fbflash = (bindec($exif["EXIF"]["Flash"]) ? "On" : "Off");
			print __(' · Blitz:', 'photoblogfb') . " {$fbflash}";
		}
		*/

		print "\n";

		if(isset($exif["IFD0"]["Make"]) && isset($exif["IFD0"]["Model"])) {
			$fbmake = ucwords(strtolower($exif["IFD0"]["Make"]));
			$fbmodel = ucwords($exif["IFD0"]["Model"]);
			print __('Kamera o. DIA-Scanner:', 'photoblogfb') . " {$fbmake}";
			print __(',', 'photoblogfb') . " {$fbmodel}";
		}

		/* Alle EXIF-Daten untereinander ausgeben */
		/**
		foreach ($exif as $key => $section) {
			foreach ($section as $name => $val) {
				echo "$key.$name: $val\n";
			}
		}
		*/
	}
}

23 Kommentare und 2 Trackbacks zu „EXIF-Daten mit PHP aus Bildern auslesen“

  1. 1
    Kommentar von tboley

    Problematisch wird es, wenn die Bilder vorher mit der GD Library in PHP bearbeitet wurden - dann gehen die EXIF-Information verloren.

  2. 2
    Kommentar von Jakob

    Ich habe versucht noch ein anderen Exif-Tag auslesen zu lassen, namentlich 'Software'. Erfolglos, aber. Ich habe es mit

    if (isset($exif["EXIF"]["Software"])) {
    print __(' · Software:') . " {$exif["EXIF"]["Software"]}";
    }

    versucht, aber, wie man so schön sagt, da kommt nüscht. Ich bin mir 99%ig sicher dass der Tag auch 'Software' heißt, hab ihn aus der Exif-pdf-Datei die du neulich verlinkt hast. Wie müsste ich den Code denn ändern damit es angezeigt wird? Danke im Voraus.
    Jakob

  3. 3
    Pingback von LoveAndPain.de - Der etwas andere künstlerische Blog
  4. 4
    Kommentar von Engel

    Hey Frank, ist ein sehr interessantes Thema. Habe auch auf meinem neuen Blog (Online seit gestern früh) mal was dazu geschrieben und auf dein Beitrag verwiesen.

    Grüße dich auch gleich mal mit diesem Kommentar. Hast mir ja schon des öfteren aus der Patsche in Sachen WordPress geholfen. Und bin nun auch wieder aktiv unter den Bloggern ;)

    lg Engel

  5. 5
    Kommentar von Tony

    Interessant wäre es, wenn man auch individuelle EXIF-Daten in dem Bild einfügen könnte. Wäre das möglich?

  6. 6
    Kommentar von Frank Bültge

    Dazu müsste man die Exif-Daten des Bildes erweitern. Einige Tools können das, da weis ich aber keinen Tipp, da ich das Ziel nie hatte. Adobe Lightroom kann das eventuell, z.B. Bild mit Tags versehen. Das Auslesen dieser Daten im Theme müsste dann in der functions.php ergänzt werden.

  7. 7
    Kommentar von Frank Bültge

    Code ist erstmal korrekt. Hast du mal alle Werte in der Schleife ausgeben lassen, vielleicht ist der Wert nicht vorhanden? Ansonsten prüfe ihn mit einem Desktoptool.

  8. 8
    Kommentar von Jakob

    Ich bin mir nicht ganz sicher was du mit "alle Werte" meinst. Alle möglichen Exif-Werte? Und: der Wert ist auf jeden Fall da, ich hab ihn mit drei verschiedenen Desktop-Tools gecheckt. Er wird auch nicht beim Upload 'fallengelassen' oder gelöscht, denn selbst wenn ich das Bild nochmal runterlade sind alle Exif-Daten, inkl. "Software" noch da.

  9. 9
    Kommentar von Frank Bültge

    @Jakob: Im ersten Codeschnipsel habe ich eine Möglichkeit dargestellt, wie man alle enthaltenen Werte und Schlüssel darstellen kann. Damit kann man in jedem Fall erst einmal auf Vorhanden prüfen. Eventuell könnte dann noch ein Fehler im Code vorliegen.

  10. 10
    Kommentar von Jakob

    Ah natürlich, das war ja auch schon in der functions.php integriert, hab ich wohl übersehen. Habe es gerade ausprobiert, auch da wird 'software' nicht angezeigt. Was wirklich komisch ist, denn der Tag ist nunmal vorhanden, und auch "ausgefüllt".
    Dennoch fiel mir noch etwas anderes auf: bei bestimmten Tags schien es Fehler bzgl. UTF-8 zu geben. Manche Werte wurde als pure Abfolge von diesen "Rauten mit Fragezeichen" dargestellt; vornehmlich die die irgendwie manuell geändert werden konnten ("EXIF.MakerNote", "EXIF.UserComment", "Firmware Version").

  11. 11
    Kommentar von Jakob

    Und gerade sah ich noch etwas: m.E. hast du die möglichen Values beim Flash falschrum gesetzt; ich denke es sollte

    $fbflash = (bindec($exif["EXIF"]["Flash"]) ? "Off" : "On");

    heißen. Zumindest habe ich das bei meinen Bildern so gesehen. Bei denen die definitiv einen Blitz benutzten stand er auf 'Off', bei anderen Tagsüber-Bildern auf 'On'.

  12. 12
    Kommentar von Frank Bültge

    Sollte eigentlich richtig sein. Entscheidend ist jedoch, was die Schleife ausgibt. Denn dort sieht man alle Schlüssel und Werte. Dementsprechend kann die Formatierung angepasst werden.
    Wer der Schlüssel nicht in der Schleife ausgegeben wird, dann ist er nicht zum Auslesen da. Es sei denn denn, er gehört nicht zu den EXIF-Daten. Im Beispiel lese ich ja EXIF- und IFD0-Daten aus.

  13. 13
    Pingback von kobak pont org » links for 2007-08-15
  14. 14
    Kommentar von Matthias

    Wie kann ich jetzt festellen, ob das exif Array Daten hatt oder nicht. Wenn keine Exif Daten da sind dann soll eine Meldung erscheinen.

    Mfg Matthias

  15. 15
    Kommentar von Frank Bültge

    Am besten mit einem Desktop-Tool, mal suchen, da gibt es Unmengen.

    Alternativ kannst du die index.php anpassen, Zeile 57:

    			} else {
    				echo 'Keine Datei vorhanden!';
    			}
    

    für die Prüfung, ob die Datei vorhanden ist und dann kann jede if-Abfrage (if($exif . . .) für EXIF-Daten mit einer else-Antwort versehen werden.

  16. 16
    Kommentar von Benjamin

    Ich glaube deine Blitzabfrage ist ein bisschen zu einfach:

    Das EXIF-Feld "Flash" ist afaik ne 7-bit Bitmaske, die mehrere Werte zulässt:
    0000001: Blitz ausgelöst
    0000100: No Return detected
    0000110: Return detected
    0001000: Blitz eingeschaltet
    0010000: Blitz ausgeschaltet
    0011000: Blitz auf Auto eingestellt
    0100000: Gerät hat gar keinen Blitz
    1000000: Rote Augen Blitz hat ausgelöst

    1011101 heißt also zum Beispiel: Rote Augen Blitz ausgelöst, Blitz stand auf Auto, Hat ausgelöst, No return

    Zumindest ist das der Stand meines "durch-die-dokus-wühlens"

    Schöne Grüße,
    Benny

  17. 17
    Kommentar von Norbert

    Hallo Frank,

    Dein Blog kann süchtig machen!
    Vielen Dank für Deine hilfreichen Seiten...aber, jetzt kommt (m)eine Frage:

    Warning: exif_read_data(WP_6.jpg) [exif_read_data]: Illegal IFD size: 2 + x1500*12 = xFC02 > x03BA in C:\Users\Public\xampp\htdocs\wordpress_1\wp-content\themes\greyfoto\functions.php on line 95
    Datum: 2009-05-18 · Uhrzeit: 14:10:44
    Blende: F/6.4 · Belichtungsdauer: 1/314s · Belichtungswert:0.0 EV · Brennweite: 13.1mm
    ISO: 100 · Blitz: Flash did not fire
    Kamera o. DIA-Scanner: Nikon, E995

    ...was ist hier zu tun, denn das sieht unter dem Foto nicht so gut aus.

    LG aus BY
    Norbert

  18. 18
    Kommentar von Frank Bültge

    @Norber: scheinbar eine Fehlermeldung, die einen Wert nicht mag; in dem Fall kannst du nur den Part auskommentieren.

  19. 19
    Kommentar von BeAvIsBeE

    Hallo,
    kleine Berichtigung zum Weiß-Abgleich:
    laut Spezifikation EXIF 2.2 hat "WhiteBalance" nur 2 Werte:
    0 = Auto white balance
    1 = Manual white balance
    Other = reserved

    Die Daten für die Licht-Verhältnisse (Daylight, Cloudy, Fluorescent,...) finden sich im EXIF-Parameter "LightSource":
    0 = unknown
    1 = Daylight
    2 = Fluorescent
    3 = Tungsten (incandescent light)
    4 = Flash
    9 = Fine weather
    10 = Cloudy weather
    11 = Shade
    12 = Daylight fluorescent (D 5700 – 7100K)
    13 = Day white fluorescent (N 4600 – 5400K)
    14 = Cool white fluorescent (W 3900 – 4500K)
    15 = White fluorescent (WW 3200 – 3700K)
    17 = Standard light A
    18 = Standard light B
    19 = Standard light C
    20 = D55
    21 = D65
    22 = D75
    23 = D50
    24 = ISO studio tungsten
    255 = other light source
    Other = reserved

  20. 20
    Kommentar von Frank Bültge

    Vielen Dank, werde ich bei mir mal berücksichtigen. Hast du noch den Link zur Spezifikation?

  21. 21
    Kommentar von BeAvIsBeE

    http://www.exif.org/specifications.html

  22. 22
    Kommentar von Denis

    Problem: Die exif Daten als solche können zwar ausgelesen werden, allerdings klappt die Funktion bei mir nicht...An dem Kameratypen (Fuji) oder an dem Bild (jpg) kann es nicht liegen, da meine Kamera die selben Bezeichnungen für die einzelnen EXIF Felder vergibt, wie in der Funktion. Was mache ich falsch?

  23. 23
    Kommentar von Frank Bültge

    @Denis: prüfe mal via extra Tool oder Firefox Erweiterung ob es lesbare Exif-Daten gibt. Wenn ja, dann lese alle über eine Schleife aus und prüfe die Werte.

  24. 24
    Kommentar von Matthias

    Kann man das Plugin/Script auch erweitern das es die Exif Infos aus mehreren Bilder ausliest. So das ich beim Beitrag verfassen mehrere Bilder über die Benutzerdefinierten Felder angeben kann?!

  25. 25
    Kommentar von Frank Bültge

    @Matthias: du kannst damit unendlich viele Bilder auslesen, das Auslesen in eine Schleife deiner Aufrufe und fertig.

Kommentar schreiben

Kommentarregeln: Bleib cool, kritisch ist in Ordnung, aber wenn du unhöflich bist, dann lösche ich deinen Kommentar. Bitte benutze deinen persönlichen Namen oder Initialen und nicht den Namen eines Unternehmens, dies würde als Spam gewertet und wird gelöscht. Der Zusammenhang zwischen Namen und URL sollte nicht offensichtlich auf Spam hindeuten! ♥ Ansonsten, vielen Dank für den Kommentar und viel Spaß mit meinem Blog.

E-Mail-Benachrichtigung bei weiteren Kommentaren.
Auch möglich: Abo ohne Kommentar.

Kommentar-Hilfe

händischer Spam:
Beachte die Kommentarregeln, jede Form von versuchtem Spam wird gelöscht. Warum und wieso steht in einem meiner Beiträge.

Bezug auf Textstellen:
Du kannst direkt bezug auf Textstellen im Beitrag nehmen. Dazu muss lediglich der Bereich im Artikel markiert werden; daraufhin erscheint ein Button, der den markierten Text in das Kommentarfeld übernimmt und als Zitat auszeichnet. Die Funktion ist nur bei aktivem JavaScript nutzbar.

xHTML:
Du kannst folgende Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <blockquote cite=""> <code> <pre> <em> <strong> <strike> <ul> <ul> <li>

Achte darauf, wenn du Code im Kommentar hinterlegen willst, dann muss der Code maskiert sein. Dann wird er nicht interpretiert. Der Code muss mit Hilfe von HTML-Entities dargestellt werden, d.h. dass man z.B. < als &lt; und > als &gt; einfügt.

E-Mail-Benachrichtigung bei neuen Kommentaren ?
Wenn der Haken in der Checkbox gesetzt ist, dann wirst du über neue Kommentare vie E-Mail informiert. Der Versand erfolgt nur, wenn du die URL in der Bestätigungs-E-Mail genutzt hast oder schon Abonnent hier im Blog bist.

Kommentar erscheint nicht:
Alle Kommentare werden manuell geprüft, freigegeben und nach Möglichkeit beantwortet. Bitte um etwas Geduld und Nachsicht.

Identifikationsbilder (Avatare):
Auf Gravatar.com kann man sich mit seiner E-Mail-Adresse registrieren und ein Bild hochladen, dann erscheint dieses Gravatar hier und in vielen weiteren Blogs.

Spamschutz:
Das Kommentarformular ist mit einem Spamschutz ausgerüstet. Solltest du diesen Artikel ohne JavaScript besuchen und kommentieren wollen, so muss du die Frage beantworten und das jeweilige Wort in das Textfeld eingeben.