"Odległość" między kolorami w PHP

Szukam funkcji, która może dokładnie przedstawić odległość między dwoma kolorami jako liczbę lub coś w tym stylu.

Na przykład Szukam tablicy wartości HEX lub tablicy RGB i chcę znaleźć najbardziej podobny kolor w tablicy dla danego koloru

Np. Przekazuję funkcji wartość RGB i zwracany jest' najbliższy ' kolor w tablicy

 13
Author: Jon Seigel, 2009-10-28

6 answers

Każdy kolor jest reprezentowany jako krotka w kodzie szesnastkowym. Aby określić bliskie dopasowania, należy odjąć każdy składnik RGB osobno.

Przykład:

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.

edit

Więc chcesz najbliższego koloru? Tworzy tablicę z wartościami szesnastkowymi każdego koloru, iterację i zwraca nazwę. Coś takiego;
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) ;

}
 19
Author: Byron Whitlock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-28 11:15:01

Oto artykuł na ten temat , który powinien dać dobrą odpowiedź.

Myślałem, że najpierw konwersja na HSL/HSV również byłaby dobrym pomysłem, ale potem zdałem sobie sprawę, że przy ekstremalnych wartościach S & L/V, H nie ma znaczenia, a w środku ma największe znaczenie.

Myślę, że jeśli chcesz prostego rozwiązania, pozostanie w przestrzeni RGB byłoby mądrzejsze. Użyłbym odległości kartezjańskiej. Jeśli rozważasz kolor R G B przeciwko Ri Gi Bi dla kilku i, chcesz i, że minimalizuje

(R - Ri)^2 + (G - Gi)^2 + (B - Bi)^2
 13
Author: Grumdrig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-12 17:18:52

Najpierw musisz wybrać odpowiednią przestrzeń kolorów, w której mają występować porównania kolorów (RGB, HSV, HSL, CMYK, itp.).

Zakładając, że chcesz wiedzieć, jak blisko dwa punkty w trójwymiarowej przestrzeni RGB są do siebie, możesz obliczyć odległość pitagorejską między nimi, tj.

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

To daje kwadrat odległości. (Pobieranie pierwiastka kwadratowego nie jest konieczne, jeśli porównujesz tylko wartości kwadratu.)

To zakłada, że chcesz traktować wartości R, G i B jednakowo. Jeśli wolisz ważyć poszczególne składniki kolorów, takie jak to, co dzieje się podczas konwersji RGB na skalę szarości, musisz dodać Współczynnik do każdego terminu odległości, tj.]}

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

Zakłada to popularną konwersję z RGB na skalę szarości 30% czerwonego + 59% Zielonego + 11% niebieskiego.

Update

To ostatnie równanie powinno być

d2 = (30*(r1-r2))**2 + (59*(g1-g2))**2 + (11*(b1-b2))**2;
 8
Author: David R Tribble,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-28 03:08:09

Bardzo prostym podejściem jest obliczenie sumarycznej odległości między trzema wymiarami. Na przykład simple_distance("12,10,255","10,10,250")=7

Bardziej wyrafinowanym podejściem byłoby wzięcie kwadratu odległości dla każdego składnika i zsumowanie ich - w ten sposób składniki znajdujące się za daleko byłyby" karane " bardziej: square_distance("12,10,255","10,10,250")=2*2+0*0+5*5=29.

Oczywiście trzeba byłoby iterację nad listą kolorów i znaleźć najbliższy.

 4
Author: Gergely Orosz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-30 14:16:23

Możesz przekonwertować wartość RGB NA HSL lub HSV. następnie kolory są łatwe do porównania: najpierw zamów kolory według odcienia, potem nasycenia, a następnie luminancji. w wynikowej kolejności dwa kolory obok siebie pojawią się jako bardzo bliskie percepcyjnie.

Uważaj, że odcień owija się wokół: dla odcienia od 0 do 255, odcień 0 i odcień 255 są bardzo bliskie.

Zobacz artykuł w Wikipedii na temat HSL http://en.wikipedia.org/wiki/HSL_and_HSV dla wzoru, który będzie pozwala na konwersję RGB do HSL

(zauważ, że inne przestrzenie kolorów, takie jak L. A. b., mogą dawać lepsze wyniki, ale konwersja jest bardziej skomplikowana)

Zdefiniujmy to matematycznie:

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

Gdzie F jest czynnikiem starannie dobranym (coś jak 256...)

powyższy wzór nie uwzględnia odcienia...

 1
Author: Adrien Plisson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-07 18:59:24

Percepcja kolorów nie jest liniowa , ponieważ ludzkie oko jest bardziej wrażliwe na określone kolory niż inne.

Musisz użyć specjalnej formuły.

Spójrz tutaj .

 1
Author: Pylyp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:01:39