2013-07-06 12 views
5

Szukam sposobu na znalezienie średniej nieokreślonej liczby kolorów. Spędziłem dużo czasu szukając sposobu, aby to zrobić. Najpierw próbowałem konwertować moje kolory do CMYK i uśredniać je, ale to nie zapewniło oczekiwanego rezultatu. Wtedy zobaczyłem, że w kilku różnych miejscach, konwersja kolorów do przestrzeni CIE L * a * b *, a następnie uśrednianie jest preferowanym sposobem robienia tego. Tak więc sprawdziłem, jak przekonwertować kolory RGB na przestrzeń LAB i przekonwertować na Javascript niezbędne algorytmy, aby tak się stało.Jak mogę znaleźć średnią z N kolorów?

Teraz mam moje kolory w przestrzeni LAB, myślałem, że będzie tak proste jak znalezienie średnio moich kolorach, więc napisałem tę funkcję, aby załatwić sprawę:

color.mixRGB = function() { 
    var cols = Array.prototype.slice.call(arguments), 
     i = cols.length, 
     lab = {l: 0, a: 0, b: 0}; 

    while(i--) { 
     if (typeof cols[i].r === "undefined" && typeof cols[i].g === "undefined" && typeof cols[i] === "undefined") { 
      console.log("Not enough parameters supplied for color " + i + "."); 
      return; 
     } 

     if(cols[i].r === 0 && cols[i].g === 0 && cols[i].b === 0) { 
      cols.splice(i, 1); 
     } else { 
      cols[i] = color.RGBtoLAB(cols[i]); 
      lab.l += cols[i].l; 
      lab.a += cols[i].a; 
      lab.b += cols[i].b;    
     } 
    } 

    lab.l /= cols.length; 
    lab.a /= cols.length; 
    lab.b /= cols.length; 

    return color.LABtoRGB(lab); 
}; 

Jeśli wejdę RGB (255, 0, 0) i RGB (0, 0, 255) do funkcji, otrzymuję RGB (202, -59, 136). Kolor ten nie jest zbliżony do Koloru Hexa, który jest średnią z tych dwóch RGB, które są RGB (128, 0, 128), a.k.a purpurowe.

Wróciłem do całego mojego kodu i do tej pory udało mi się ustalić, że problem nie dotyczy żadnego z moich algorytmów konwersji przez podwójne i potrójne sprawdzenie ich pod kątem Color Hexa i EasyRGB. Oznacza to, że: a) kwestia musi leżeć po tym, jak uśredniam kolory lub b) zostałem źle poinformowany i nie powinienem próbować mieszać kolorów w przestrzeni CIE L * a * b *.

Czego dokładnie tu brakuje? Używając mojego aktualnego algorytmu, dlaczego uśrednianie RGB (255, 0, 0) i RGB (0, 0, 255) nie daje takich samych wyników, jakie zapewnia Kolor Hexa (lub nawet estymacja wizualna)? (here's a fiddle mojego problemu)

+2

Uśrednianie w jednym obszarze kolorów to nie to samo, co uśrednianie w innej przestrzeni kolorów. Nie można oczekiwać takich samych rezultatów. –

+0

Rozumiem to; dlaczego jest to istotne? –

+1

Bo wydajesz się być zaskoczony, że uzyskujesz różne wyniki;) (Chociaż możliwe, że źle rozumiem rzeczy ...) –

Odpowiedz

3

Powiedzmy, że masz kolory zdefiniowane przez R0, G0, B0 i R1, G1, B1. Następnie miesza/średni kolor będzie mieć następujące wartości RGB:

RA = (R0+R1)/2; 
GA = (G0+G1)/2; 
BA = (B0+B1)/2; 

to wszystko, w zasadzie.

+0

Myślę, że czegoś brakuje. Czy to naprawdę może być takie proste? Zakodowałem to algo i po prostu robię małe testy. –

+0

To jest sposób Color Hexa. Co nie jest w porządku, jeśli mnie pytasz. Spróbuj zrobić to samo w przestrzeni kolorów HLS lub HSB. LaB może być mylący. –

+0

Cóż, wydaje się, że to wystarczy (to na pewno wszystko, czego potrzebuję). Chyba na razie przyjmuję twoją odpowiedź. Dzięki, że byłeś głosem zdrowego rozsądku, podczas gdy ja błądziłam z powodu zbyt skomplikowanych przestrzeni kolorów. :-) –

2

Zwrot zerowy oznacza, że ​​wystąpił błąd.

color.mixRGB = function() { 
    var cols = Array.prototype.slice.call(arguments), 
     i = cols.length, 
     rTotal = 0, gTotal = 0, rTotal = 0, colTotal = 0; 

    while(i--) { 
     // NOTE: you had && in your code, I think they should be || 
     if (typeof cols[i].r === "undefined" || typeof cols[i].g === "undefined" || typeof cols[i] === "undefined") { 
      console.log("Not enough parameters supplied for color " + i + "."); 
      return null; 
     } 
     colTotal++; 
     rTotal += cols[i].r; 
     gTotal += cols[i].g; 
     bTotal += cols[i].b; 
    } 
    if(colTotal === 0) return null; 

    // I am not sure what you are trying to return, just build it up with your rgb values 
    return (new color(Math.round(rTotal/colTotal), Math.round(gTotal/colTotal), Math.round(bTotal/colTotal))); 
}; 
Powiązane problemy