Nie jestem pewien, czy jest to możliwe, ale chciałbym napisać skrypt, który zwróciłby średnią hex
lub rgb
wartość obrazu. Wiem, że można to zrobić w AS, ale chcę to zrobić w JavaScript.
Nie jestem pewien, czy jest to możliwe, ale chciałbym napisać skrypt, który zwróciłby średnią hex
lub rgb
wartość obrazu. Wiem, że można to zrobić w AS, ale chcę to zrobić w JavaScript.
Odpowiedzi:
AFAIK, jedynym sposobem na to jest <canvas/>
...
DEMO V2 : http://jsfiddle.net/xLF38/818/
Uwaga, będzie to działać tylko w przypadku obrazów w tej samej domenie i w przeglądarkach obsługujących kanwę HTML5:
function getAverageRGB(imgEl) {
var blockSize = 5, // only visit every 5 pixels
defaultRGB = {r:0,g:0,b:0}, // for non-supporting envs
canvas = document.createElement('canvas'),
context = canvas.getContext && canvas.getContext('2d'),
data, width, height,
i = -4,
length,
rgb = {r:0,g:0,b:0},
count = 0;
if (!context) {
return defaultRGB;
}
height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;
width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;
context.drawImage(imgEl, 0, 0);
try {
data = context.getImageData(0, 0, width, height);
} catch(e) {
/* security error, img on diff domain */
return defaultRGB;
}
length = data.data.length;
while ( (i += blockSize * 4) < length ) {
++count;
rgb.r += data.data[i];
rgb.g += data.data[i+1];
rgb.b += data.data[i+2];
}
// ~~ used to floor values
rgb.r = ~~(rgb.r/count);
rgb.g = ~~(rgb.g/count);
rgb.b = ~~(rgb.b/count);
return rgb;
}
W przypadku IE sprawdź excanvas .
'rgb('+rgb.r+','+rgb.b+','+rgb.g+')'
i tak powinno być 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')'
. to dziwne, gdy dominującym kolorem jest niebieski, a wynik jest zielony :).
img.crossOrigin = '';
przed ustawieniem src
atrybutu. Znaleziono na: coderwall.com/p/pa-2uw
count === length / 4 / blockSize
;)
Pomyślałem, że opublikuję projekt, na który niedawno natknąłem się, aby uzyskać dominujący kolor:
Skrypt do pobierania dominującego koloru lub reprezentatywnej palety kolorów z obrazu. Używa javascript i canvas.
Inne rozwiązania wspominające i sugerujące dominujący kolor nigdy tak naprawdę nie odpowiadają na pytanie w odpowiednim kontekście („in javascript”). Mam nadzieję, że ten projekt pomoże tym, którzy chcą to zrobić.
„Dominant Color” jest trudny. To, co chcesz zrobić, to porównać odległość między każdym pikselem a każdym innym pikselem w przestrzeni kolorów (odległość euklidesowa), a następnie znaleźć piksel, którego kolor jest najbliższy każdemu innemu kolorowi. Ten piksel jest kolorem dominującym. Przeciętny kolor to zwykle błoto.
Żałuję, że nie mam tutaj MathML, aby pokazać odległość euklidesową. Wygoogluj to.
Powyższe wykonanie wykonałem w przestrzeni kolorów RGB przy użyciu PHP / GD tutaj: https://gist.github.com/cf23f8bddb307ad4abd8
Jest to jednak bardzo kosztowne obliczeniowo. Spowoduje to awarię systemu przy dużych obrazach i na pewno spowoduje awarię przeglądarki, jeśli spróbujesz tego w kliencie. Pracowałem nad refaktoryzacją mojego wykonania, aby: - przechowywać wyniki w tabeli przeglądowej do wykorzystania w przyszłości w iteracji po każdym pikselu. - dzielenie dużych obrazów na siatki o wymiarach 20px 20px w celu zlokalizowanej dominacji. - użyć odległości euklidesowej między x1y1 i x1y2, aby obliczyć odległość między x1y1 i x1y3.
Daj mi znać, jeśli zrobisz postęp w tej dziedzinie. Z przyjemnością to zobaczę. Zrobię to samo.
Canvas to zdecydowanie najlepszy sposób na zrobienie tego w kliencie. SVG nie jest, SVG jest oparty na wektorach. Po zakończeniu wykonywania następną rzeczą, którą chcę zrobić, jest uruchomienie tego w płótnie (może z pracownikiem sieciowym do obliczenia całkowitej odległości każdego piksela).
Inną rzeczą do przemyślenia jest to, że RGB nie jest dobrą przestrzenią kolorów do tego, ponieważ odległość euklidesowa między kolorami w przestrzeni RGB nie jest zbyt bliska odległości wizualnej. Lepszą przestrzenią kolorów do tego może być LUV, ale nie znalazłem do tego dobrej biblioteki ani żadnych algorytmów konwersji RGB na LUV.
Zupełnie innym podejściem byłoby posortowanie kolorów w tęczy i utworzenie histogramu z tolerancją uwzględniającą różne odcienie koloru. Nie próbowałem tego, ponieważ sortowanie kolorów w tęczy jest trudne, podobnie jak histogramy kolorów. Mogę spróbować jako następny. Ponownie, daj mi znać, jeśli zrobisz tutaj jakiś postęp.
Po pierwsze: można to zrobić bez HTML5 Canvas lub SVG.
W rzeczywistości komuś udało się wygenerować pliki PNG po stronie klienta za pomocą JavaScript , bez płótna lub SVG, używając schematu URI danych .
Po drugie: możesz w ogóle nie potrzebować Canvas, SVG ani żadnego z powyższych.
Jeśli potrzebujesz tylko przetwarzać obrazy po stronie klienta, bez ich modyfikowania, wszystko to nie jest potrzebne.
Możesz pobrać adres źródłowy z tagu img na stronie, wysłać żądanie XHR - najprawdopodobniej będzie pochodzić z pamięci podręcznej przeglądarki - i przetworzyć go jako strumień bajtów z Javascript.
Będziesz potrzebować dobrego zrozumienia formatu obrazu. (Powyższy generator jest częściowo oparty na źródłach libpng i może stanowić dobry punkt wyjścia).
Powiedziałbym, że poprzez tag HTML canvas.
Możesz znaleźć tutaj post @Georg, który mówi o małym kodzie autora Opery:
// Get the CanvasPixelArray from the given coordinates and dimensions.
var imgd = context.getImageData(x, y, width, height);
var pix = imgd.data;
// Loop over each pixel and invert the color.
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i ] = 255 - pix[i ]; // red
pix[i+1] = 255 - pix[i+1]; // green
pix[i+2] = 255 - pix[i+2]; // blue
// i+3 is alpha (the fourth element)
}
// Draw the ImageData at the given (x,y) coordinates.
context.putImageData(imgd, x, y);
To odwraca obraz, używając wartości R, G i B każdego piksela. Możesz łatwo zapisać wartości RGB, a następnie zaokrąglić tablice czerwonego, zielonego i niebieskiego, a na koniec przekonwertować je z powrotem na kod HEX.
Niedawno natknąłem się na wtyczkę jQuery, która robi to, czego pierwotnie chciałem https://github.com/briangonzalez/jquery.adaptive-backgrounds.js, jeśli chodzi o uzyskanie dominującego koloru z obrazu.
Javascript nie ma dostępu do danych koloru poszczególnych pikseli obrazu. Przynajmniej może nie do html5 ... w tym momencie ma się rozumieć, że będziesz mógł narysować obraz na płótnie, a następnie sprawdzić płótno (być może nigdy tego nie robiłem).
Osobiście połączyłbym Złodzieja Kolorów z tą zmodyfikowaną wersją Nazwy tego Koloru, aby uzyskać więcej niż wystarczający zestaw dominujących kolorów dla obrazów.
Przykład:
Rozważ następujący obraz:
Możesz użyć następującego kodu, aby wyodrębnić dane obrazu związane z dominującym kolorem:
let color_thief = new ColorThief();
let sample_image = new Image();
sample_image.onload = () => {
let result = ntc.name('#' + color_thief.getColor(sample_image).map(x => {
const hex = x.toString(16);
return hex.length === 1 ? '0' + hex : hex;
}).join(''));
console.log(result[0]); // #f0c420 : Dominant HEX/RGB value of closest match
console.log(result[1]); // Moon Yellow : Dominant specific color name of closest match
console.log(result[2]); // #ffff00 : Dominant HEX/RGB value of shade of closest match
console.log(result[3]); // Yellow : Dominant color name of shade of closest match
console.log(result[4]); // false : True if exact color match
};
sample_image.crossOrigin = 'anonymous';
sample_image.src = document.getElementById('sample-image').src;
Chodzi o „kwantyzację koloru”, która ma kilka podejść, takich jak MMCQ (zmodyfikowana kwantyzacja mediany cięcia) lub OQ (kwantyzacja ośmiokrotnie). Inne podejście wykorzystuje K-Means do uzyskania klastrów kolorów.
Złożyłem wszystko razem, ponieważ szukałem rozwiązania dla tvOS
miejsca, w którym istnieje podzbiór XHTML, który nie ma <canvas/>
elementu:
Wygeneruj dominujące kolory dla obrazu RGB za pomocą XMLHttpRequest
Mniej dokładny, ale najszybszy sposób na uzyskanie przeciętnego koloru obrazu z datauri
obsługą:
function get_average_rgb(img) {
var context = document.createElement('canvas').getContext('2d');
if (typeof img == 'string') {
var src = img;
img = new Image;
img.setAttribute('crossOrigin', '');
img.src = src;
}
context.imageSmoothingEnabled = true;
context.drawImage(img, 0, 0, 1, 1);
return context.getImageData(1, 1, 1, 1).data.slice(0,3);
}
Istnieje internetowe narzędzie pickimagecolor.com, które pomaga znaleźć średni lub dominujący kolor obrazu. Wystarczy załadować obraz z komputera, a następnie kliknąć go. Daje średni kolor w HEX, RGB i HSV. Znajduje również odcienie pasujące do tego koloru do wyboru. Używałem go wiele razy.