Não tenho certeza se isso é possível, mas estou procurando escrever um script que retorne a média hex
ou o rgb
valor de uma imagem. Eu sei que isso pode ser feito em AS, mas procurando fazê-lo em JavaScript.
Não tenho certeza se isso é possível, mas estou procurando escrever um script que retorne a média hex
ou o rgb
valor de uma imagem. Eu sei que isso pode ser feito em AS, mas procurando fazê-lo em JavaScript.
Respostas:
AFAIK, a única maneira de fazer isso é com <canvas/>
...
DEMO V2 : http://jsfiddle.net/xLF38/818/
Observe que isso só funcionará com imagens no mesmo domínio e em navegadores que suportam tela 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;
}
Para o IE, verifique excanvas .
'rgb('+rgb.r+','+rgb.b+','+rgb.g+')'
e deve ser 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')'
. é estranho quando a cor dominante é azul, mas o resultado é verde :).
img.crossOrigin = '';
antes de definir o src
atributo. Encontrado em: coderwall.com/p/pa-2uw
count === length / 4 / blockSize
;)
Decidi postar um projeto que descobri recentemente para obter a cor dominante:
Um script para obter a cor dominante ou uma paleta de cores representativa de uma imagem. Usa javascript e canvas.
As outras soluções que mencionam e sugerem a cor dominante nunca respondem realmente à pergunta no contexto adequado ("em javascript"). Espero que este projeto ajude aqueles que desejam fazer exatamente isso.
"Cor dominante" é complicada. O que você deseja fazer é comparar a distância entre cada pixel e todos os outros pixels no espaço de cores (distância euclidiana) e, em seguida, encontrar o pixel cuja cor é mais próxima de todas as outras cores. Esse pixel é a cor dominante. A cor média geralmente será lama.
Gostaria de ter o MathML aqui para mostrar a distância euclidiana. Pesquise no Google.
Eu realizei a execução acima no espaço de cores RGB usando PHP / GD aqui: https://gist.github.com/cf23f8bddb307ad4abd8
No entanto, isso é muito caro do ponto de vista computacional. Irá travar seu sistema em imagens grandes e definitivamente travará seu navegador se você tentar no cliente. Tenho trabalhado na refatoração de minha execução para: - armazenar os resultados em uma tabela de pesquisa para uso futuro na iteração de cada pixel. - para dividir imagens grandes em grades de 20px 20px para dominância localizada. - para usar a distância euclidiana entre x1y1 e x1y2 para descobrir a distância entre x1y1 e x1y3.
Informe se você progredir nessa área. Eu ficaria feliz em ver isso. Eu vou fazer o mesmo.
O Canvas é definitivamente a melhor maneira de fazer isso no cliente. SVG não é, SVG é baseado em vetor. Depois de terminar a execução, a próxima coisa que quero fazer é executá-la na tela (talvez com um webworker para o cálculo da distância geral de cada pixel).
Outra coisa a se pensar é que RGB não é um bom espaço de cores para fazer isso, porque a distância euclidiana entre as cores no espaço RGB não é muito próxima da distância visual. Um espaço de cores melhor para fazer isso pode ser LUV, mas eu não encontrei uma boa biblioteca para isso, ou qualquer algoritmo de conversão de RGB para LUV.
Uma abordagem totalmente diferente seria classificar suas cores em um arco-íris e construir um histograma com tolerância para considerar os vários tons de uma cor. Não tentei fazer isso porque classificar as cores em um arco-íris é difícil, assim como os histogramas de cores. Eu posso tentar isso a seguir. Novamente, deixe-me saber se você fizer algum progresso aqui.
Primeiro: isso pode ser feito sem HTML5 Canvas ou SVG.
Na verdade, alguém conseguiu gerar arquivos PNG do lado do cliente usando JavaScript , sem canvas ou SVG, usando o esquema de URI de dados .
Segundo: você pode realmente não precisar do Canvas, SVG ou qualquer um dos acima.
Se você só precisa processar as imagens no lado do cliente, sem modificá-las, tudo isso não é necessário.
Você pode obter o endereço de origem da tag img na página, fazer uma solicitação XHR para ele - provavelmente virá do cache do navegador - e processá-lo como um fluxo de bytes de Javascript.
Você precisará de um bom conhecimento do formato da imagem. (O gerador acima é parcialmente baseado em fontes libpng e pode fornecer um bom ponto de partida.)
Eu diria por meio da tag canvas HTML.
Você pode encontrar aqui um post de @Georg falando sobre um pequeno código do desenvolvedor do Opera:
// 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);
Isso inverte a imagem usando os valores R, G e B de cada pixel. Você pode facilmente armazenar os valores RGB e, em seguida, arredondar as matrizes Red, Green e Blue e, finalmente, convertê-los de volta em um código HEX.
Recentemente, encontrei um plugin jQuery que faz o que eu queria originalmente https://github.com/briangonzalez/jquery.adaptive-backgrounds.js com relação a obter uma cor dominante de uma imagem.
Javascript não tem acesso aos dados de cor de pixel individual de uma imagem. Pelo menos, talvez não até html5 ... nesse ponto, é lógico que você será capaz de desenhar uma imagem em uma tela e, em seguida, inspecionar a tela (talvez, eu nunca tenha feito isso sozinho).
Eu pessoalmente combinaria o Color Thief junto com esta versão modificada de Name that Color para obter uma matriz mais do que suficiente de resultados de cores dominantes para imagens.
Exemplo:
Considere a seguinte imagem:
Você pode usar o seguinte código para extrair dados de imagem relacionados à cor dominante:
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;
Trata-se de "Quantização de Cor" que tem várias abordagens como MMCQ (Quantização de Corte Mediana Modificada) ou OQ (Quantização Octree). Abordagens diferentes usam K-Means para obter grupos de cores.
Eu juntei tudo aqui, pois estava encontrando uma solução para tvOS
onde há um subconjunto de XHTML que não tem <canvas/>
elemento:
Gere as cores dominantes para uma imagem RGB com XMLHttpRequest
Maneira menos precisa, mas mais rápida de obter a cor média da imagem com datauri
suporte:
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);
}
Existe uma ferramenta online pickimagecolor.com que o ajuda a encontrar a média ou a cor dominante da imagem. Você só precisa fazer o upload de uma imagem do seu computador e clicar na imagem. Fornece a cor média em HEX, RGB e HSV. Ele também encontra os tons de cores correspondentes a essa cor para escolher. Eu usei várias vezes.