Histogramme für Bilder werden meist zur Beurteilung einer Häufigkeitsverteilung des Bildes benutzt. Dies kann der Durchschnittswert der Helligkeit sein, dies kann aber auch der Anteil der einzelnen Farben sein. In diversen Programmen wie zum Beispiel Photoshop werden diese Informationen gleich mit angezeigt. Vor einiger Zeit hatte ich solche Histogramme in der Bildergalerie mit eingebunden. So konnte man die Helligkeit und die Anteile der RGB- bzw. CYMK-Werte als Histrogramm ansehen. In diesem Beitrag ein kleiner Einblick wie das ganze mit PHP funktioniert.
Erfassung der Helligkeitsverteilung
[bild]1520[/bild]
Das Beispiel zeigt die Helligkeitsverteilung von 0 (dunkel) bis 255 (hell) an. Die Höhe der Amplituden ist dabei der Anteil wie oft dieser Wert im Bild gefunden wurde. Natürlich wird hier nicht jedes Pixel erfasst. Bei 800x600 wären das 480000 Pixel. Hört sich nicht sonderlich viel an, aber um die Werte in einen Array oder Object zu speichern, ist das eine ganze Menge an Daten die im Speicher erst einmal zwischen gespeichert werden müssen.
Damit das Abtasten vom Bild etwas schneller geht, wird das Bild in ein Raster geteilt. Dieses Raster passt sich automatisch an die Bildgröße (Breite und Höhe) an. Nehmen wir an das Raster hat 100 vertikale und 100 horizontale Punkte, dann ergeben sich 10000 Bildpunkte zum abtasten. Wobei dann hier die Daten noch überschaubar wären.
Egal ob schwarz/weiß oder ein RGB-Kanal, der jeweilige Anteil wird von 0 (dunkel) bis 255 (hell) erfasst und in ein Array oder Object gespeichert. Um die einzelnen Werte auszulesen kommt die GDlib zum Einsatz. Um die Helligkeit bzw. Luminosity des Bildes zu erfassen, habe ich folgendes Verfahren benutzt:
<?php
// Array für Werte 0 bis 255
$l_array = Array();
for ($x = 1; $x < $this->im_bb; $x += $this->raster ) {
for ($y = 1; $y < $this->im_hh; $y += $this->raster ) {
// Farbinformationen ermitteln
$rgb = imagecolorsforindex($this->im, imagecolorat($this->im, $x, $y));
$Nr = pow(($rgb['red']/255),2.2);
$Ng = pow(($rgb['green']/255),2.2);
$Nb = pow(($rgb['blue']/255),2.2);
$L = ($this->fr * $Nr) + ($this->fg * $Ng) + ($this->fb * $Nb);
$L = round(255 * $L);
$l_array[$L] += 1;
}
}
?>