PHP und Farbe – Helligkeit, Kontrast und Farbunterschied berechnen
Beim Sinieren über SEO und On-Page Optimierung kreisten meine Gedanken kürzlich um Folgendes:
Um eine Webseite „oben“ in den Google Suchergebnissen zu positionieren braucht es Content. Eine Überschrift „Keyword1 Keyword2“ hilft bereits weiter.
Erst recht, wenn diese über einem themenrelevanten Text mit einer bestimmten Keyword Dichte steht. Nun könnte es erstrebenswert sein, eine Seite unter einer Keyword Kombination finden zu lassen, die man seinen Besuchern nicht als prominente Überschrift oder Textblock präsentieren möchte. CSS bietet natürlich die Möglichkeit < h1 > Tags oder andere Elemente weniger dominant zu formatieren, doch darum soll es hier nicht gehen.
In den 90er Jahren soll es tatsächlich funktioniert haben, Überschriften oder gar Texte mit weisser Schrift auf weissem Hintergrund einzubinden und die Suchmaschinen so zu täuschen und sich eine bessere Position in den Trefferlisten zu erschleichen.
SCHON SEIT LÄNGERER ZEIT FUNKTIONIERT DIES NICHT MEHR! (vgl. hierzu http://www.seo-united.de/onpage-optimierung/content-texte.html und https://support.google.com/webmasters/answer/66353?hl=en) doch auch darum soll es hier nicht gehen.
Mich beschäftigt viel eher die Frage: „Wie schafft es Google oder generell eine Maschine dies zu erkennen (und zu bestrafen)?“. Denkt man darüber nach, kommt man zur Frage: Wie kann man z.B. einem PHP Skript beibringen den Helligkeitsunterschied zwischen 2 Farben zu bestimmen? Der Unterschied zwischen Hellgelb (#FFFFE0) und weissem Hintergrund müsste ja deutlich kleiner sein, als der Unterschied zwischen Dunkelbraun (#654321) und dem selben Hintergrund. Aber wie kann man dies berechnen?
Fangen wir mit den Grundlagen der Farbentheorie an: Im HTML Code einer Internetseite werden Farben als sog. HEX Code definiert (z.B #FFFFFF für weiss). http://de.wikipedia.org/wiki/Hexadezimale_Farbdefinition
Dieser Code entspricht einfach der hexadezimalen Schreibweise des entsprechenden RGB Codes, der jede Farbe in einen Rot, Grün und Blau Anteil zwischen 0 und 255 aufspaltet. Weiss hat die Anteile R=255, G=255 und B=255. Schwarz hat die Anteile R=0, G=0, B=0.
Nun gibt es das interessante Konzept des RGB Farbwürfels. Die x, y und z Achse dieses Würfels repräsentieren die Farben Rot, Grün und Blau und gehen jeweils von 0 bis 255. Jede Farbe kann nun durch 3 Koordinaten beschrieben werden und entspricht einem Punkt innerhalb dieses Würfels.

Soweit so gut. Noch interessanter wird es, wenn man sich mit der Helligkeit dieser Farben beschäftigt. Je näher der beschriebene „Farbpunkt“ an der weissen Ecke dieses Würfels zu liegen kommt, desto heller ist die entsprechende Farbe. Das bedeutet aber auch, dass es einen Grünton gibt, dessen Helligkeit exakt der eines (z. B.) Rottones in der selben Entfernung der weissen Ecke entspricht. Eine bestimmte Helligkeit kann man sich also als Ansammlung/Fläche von Punkten innerhalb des Farbwürfels vorstellen, die denselben Abstand zur „weissen Ecke“ haben. Diese Fläche hat die Form eines Kugelsegments.
Diesen Abstand könnte man nun berechnen und daraus auf die Helligkeit einer beliebigen Farbe schliessen:

RGB-Farbe 248,155,253 (http://www.colorhexa.com/f89bfd)
255-248 = 7
255-155 = 100
255-253 = 2
Summe Δ 109

RGB-Farbe 204,204,204 (http://www.colorhexa.com/cccccc)
255-204 = 51
255-204 = 51
255-204 = 51
Summe Δ 153
Je kleiner diese Zahl, desto näher ist die betrachtete Farbe an der weissen Ecke, sprich umso heller. Und je gösser diese Zahl desta dunkler die entsprechende Farbe:

Nun ist es natürlich ein Leichtes diese Zahlen per PHP miteinander zu vergleichen um herauszufinden, wie gross der Helligkeitsunterschied zwischen den beiden (z.B. Hintergrundfarbe und Textfarbe) ist. In unserem Fall 153-109=44. Nun könnten man einen Schwellenwert definieren (z.B. 50), ab dem eine Seite wegen schlechter Lesbarkeit oder vermeintlicher Betrugsversuche abgestraft wird.
//PHP Hex in RGB umrechnen
$hex_code_text="#000000";
//Nachdem der Hexcode mittels substr in Zweierpäckchen zerteilt wurde, wandelt die Funktion hexdec die Hexadezimalzahlen in Dezimalwerte um
$red = hexdec(substr($hex_code_text, 1, 2));
$green = hexdec(substr($hex_code_text, 3, 2));
$blue = hexdec(substr($hex_code_text, 5, 2));
echo "RGB-Code: (".$red."/".$green."/".$blue.")
";
//Differenz der einzelnen Werte von 255 ermitteln
$dif_white_red=255-$red;
$dif_white_green=255-$green;
$dif_white_blue=255-$blue;
$dif_white_sum=$dif_white_red+$dif_white_green+$dif_white_blue;
echo "Differenz zu weiss: ".$dif_white_sum."
";
//Differenz zu beliebiger Hintergrundfarbe
$hex_code_bg="#CCCCCC";
$bg_red = hexdec(substr($hex_code_bg, 1, 2));
$bg_green = hexdec(substr($hex_code_bg, 3, 2));
$bg_blue = hexdec(substr($hex_code_bg, 5, 2));
//durch abs wird sichergestellt, dass die Werte nicht negativ werden.
$dif_bg_red=abs($bg_red-$red);
$dif_bg_green=abs($bg_red-$green);
$dif_bg_blue=abs($bg_red-$blue);
$dif_bg_sum=$dif_bg_red+$dif_bg_green+$dif_bg_blue;
echo "Differenz zur Hintergrundfarbe: ".$dif_bg_sum;
P.S.: Natürlich gibt es andere Farbräume um Farben zu beschreiben, die ggf. zu einem anderen Ergebniss führen würden. Auch sind Farbeindrücke immer subjektiv. Was für den Einen noch gut lesbar erscheint, lässt den Anderen bereits die Augen zusammenkneifen. Es ist ausserdem bekannt, dass Farben umso heller erscheinen, je gesättigter sie sind (Helmholtz Kohlrausch Effekt: http://en.wikipedia.org/wiki/Helmholtz%E2%80%93Kohlrausch_effect). Als erste Näherung und um das Konzept zu verstehen, soll die hier vorgestellte Lösung jedoch genügen.