2009-10-27 11 views
12

Ich bin auf der Suche nach einer Funktion, die den Abstand zwischen zwei Farben als eine Zahl oder etwas genau darstellen kann."Abstand" zwischen Farben in PHP

Zum Beispiel Ich suche eine Reihe von HEX-Werten oder RGB-Arrays haben, und ich möchte für eine gegebene Farbe

zB die ähnlichste Farbe in der Matrix zu finden. Ich gebe einer Funktion einen RGB-Wert und die 'nächste' Farbe im Array wird zurückgegeben

+0

Ähnliche Fragen: http://stackoverflow.com/questions/1313/followup-finding-an-accurate-distance-bww-colors – Kai

Antwort

19

Jede Farbe wird als Tupel im HEX-Code dargestellt. Um enge Übereinstimmungen zu ermitteln, müssen Sie jede RGB-Komponente separat subtrahieren.

Beispiel:

Color 1: #112233 
Color 2: #122334 
Color 3: #000000 

Difference between color1 and color2: R=1, G=1 B=1 = 0x3 
Difference between color3 and color1: R=11, G=22, B=33 = 0x66 

So color 1 and color 2 are closer than 
1 and 3. 

bearbeiten

So ermitteln Sie den nächsten Namen Farbe wünschen? Erstellen Sie ein Array mit den Hex-Werten jeder Farbe, iterieren Sie es und geben Sie den Namen zurück. Etwas wie das;

function getColor($rgb) 
{ 
    // these are not the actual rgb values 
    $colors = array(BLUE =>0xFFEEBB, RED => 0x103ABD, GREEN => 0x123456); 

    $largestDiff = 0; 
    $closestColor = ""; 
    foreach ($colors as $name => $rgbColor) 
    { 
     if (colorDiff($rgbColor,$rgb) > $largestDiff) 
     { 
      $largestDiff = colorDiff($rgbColor,$rgb); 
      $closestColor = $name; 
     } 

    } 
    return $closestColor; 

} 

function colorDiff($rgb1,$rgb2) 
{ 
    // do the math on each tuple 
    // could use bitwise operates more efficiently but just do strings for now. 
    $red1 = hexdec(substr($rgb1,0,2)); 
    $green1 = hexdec(substr($rgb1,2,2)); 
    $blue1 = hexdec(substr($rgb1,4,2)); 

    $red2 = hexdec(substr($rgb2,0,2)); 
    $green2 = hexdec(substr($rgb2,2,2)); 
    $blue2 = hexdec(substr($rgb2,4,2)); 

    return abs($red1 - $red2) + abs($green1 - $green2) + abs($blue1 - $blue2) ; 

} 
+0

Ich verstehe, ich brauche die RGB-Werte, aber ich bin auf der Suche nach einer Funktion, die für kann die "ähnlichste" Farbe in einem Array für eine bestimmte Farbe zurückgeben. Ein einfaches Beispiel: [BLAU, ROT, DARKRED, GRÜN] Wurde die Funktion der Farbe HELL, aus dem Array oben, Id erwarten, dass die Funktion zurückzukehren „BLUE“ Prost Wenn Sie Philip – Phil

+0

gegeben Hexadezimalwerte werden überhaupt nicht angezeigt, erstellen Sie einfach eine Funktion mit einer großen switch-Anweisung, die den Farbnamen übernimmt und nur den Namen zurückgibt, der Ihrer Meinung nach der nächste ist. –

+3

Die colofDiff-Funktion ist gut, aber muss einen Fehler im Gegenzug beheben, "zurück abs ($ red1 - $ red2) + abs ($ green1 - $ green2) + abs ($ blue1 - $ blue2);" – Cesar

4

Ein sehr einfacher Ansatz ist es, den zusammengefassten Abstand zwischen den drei Dimensionen zu berechnen. Zum Beispiel Simple_distance ("12,10,255", "10,10,250") = 7

Ein ausgefeilterer Ansatz wäre, das Quadrat der Abstände für jede Komponente zu nehmen und diese zu addieren - auf diese Weise würden Komponenten, die zu weit sind, nicht sein "bestraft" mehr: square_distance ("12,10,255", "10,10,250") = 2 * 2 + 0 * 0 + 5 * 5 = 29.

Natürlich müssten Sie über die Liste der Farben iterieren und die nächste finden.

1

können Sie Ihren RGB-Wert in HSL oder HSV konvertieren. dann sind die Farben einfach zu vergleichen: Farben zuerst nach Farbton, dann nach Sättigung, dann nach Helligkeit. In der resultierenden Reihenfolge erscheinen 2 Farben nebeneinander als sehr nahe wahrnehmbar.

Achten Sie darauf, dass der Farbton sich umschließt: Bei einem Farbton von 0 bis 255 sind ein Farbton von 0 und ein Farbton von 255 sehr nahe.

siehe Wikipedia-Artikel auf HSL http://en.wikipedia.org/wiki/HSL_and_HSV für die Formel, die Sie RGB

zu HSL umwandeln können (beachten Sie, dass andere Farbräume, wie Lab, können bessere Ergebnisse, aber Umwandlung ist komplizierter)

lassen Sie uns dies mathematisch definieren:

distance(A(h,s,l), B(h,s,l)) = (A(h)-B(h)) * F^2 + (A(s)-B(s)) * F + (A(l)-B(l)) 

wobei F ein Faktor sorgfältig gewählt ist (so etwas wie 256 ...)

Die obige Formel berücksichtigt nicht den Farbtonumlauf ...

+0

das macht keinen Sinn. Wenn die Farben A und B einen leichten Unterschied in der Helligkeit und dem gleichen Farbton hatten und die Farben A und C die gleiche Helligkeit und einen großen Farbtonunterschied hatten (z. B. ist einer rot und der andere grün), so ist der Abstand zwischen A und B wäre größer als der Abstand zwischen A und C ... –

+0

Es scheint, Sie missverstanden die Reihenfolge, die ich vorschlage: Sie bestellen zuerst nach Farbton, dann bestellen Sie Farben mit gleichem Farbton durch Sättigung, schließlich bestellen Sie Farben mit gleichem Farbton und Sättigung durch Luminanz. Bei dieser Reihenfolge haben die Farben A und B den gleichen Farbton und der Abstand (A, B) ist kleiner als (A, C). –

+0

Ich bearbeitete meine Antwort, um eine kleine mathematische Formel einzuschließen, die hoffentlich hilft, die Reihenfolge besser zu verstehen ... –

12

Here is a paper on the subject, die eine gute Antwort geben sollte.

Ich dachte, dass die Umwandlung zu HSL/HSV zuerst eine gute Idee auch wäre, aber dann erkannte ich, dass bei extremen Werten von S/H nicht wichtig ist, und in der Mitte, ist es am wichtigsten .

Ich denke, wenn Sie eine einfache Lösung wollen, wäre der Aufenthalt im RGB-Raum klüger. Ich würde kartesische Distanz verwenden. Wenn Sie erwägen, Farbe R G B gegen Ri Gi Bi für mehrere i, möchten Sie die i die

(R - Ri)^2 + (G - Gi)^2 + (B - Bi)^2 
8

Zuerst Sie die Farbvergleiche in (RGB, HSV, HSL auftreten wollen, müssen wählen th entsprechenden Farbraum minimiert, CMYK usw.).

Angenommen, Sie wollen wissen, wie nahe zwei Punkte in der 3-dimenionsal RGB-Raum zueinander sind, können Sie den pythagoreischen Abstand zwischen ihnen, das heißt, diese tatsächlich

d2 = (r1 - r2)**2 + (g1 - g2)**2 + (b1 - b2)**2; 

berechnen gibt Ihnen das Quadrat die Distanz. (Die Verwendung der Quadratwurzel ist nicht erforderlich, wenn Sie nur die quadrierten Werte vergleichen.)

Dies setzt voraus, dass Sie die R-, G- und B-Werte gleich behandeln möchten. Wenn Sie lieber die einzelnen Farbkomponenten gewichten würde, wie zum Beispiel, was passiert, wenn Sie RGB in Graustufen umwandeln, müssen Sie auf jeden Begriff des Abstandes einen Koeffizienten addieren, dh

d2 = 30*(r1-r2)**2 + 59*(g1-g2)**2 + 11*(b1-b2)**2; 

Diese die beliebte Umwandlung geht davon aus, RGB zu Graustufen von 30% rot + 59% grün + 11% blau.

aktualisieren

Diese letzte Gleichung wahrscheinlich

d2 = (30*(r1-r2))**2 + (59*(g1-g2))**2 + (11*(b1-b2))**2;