Como pegar as cores de uma imagem via Javascript?

Como pegar as cores de uma imagem via Javascript?

13 de junho de 2020 0 Por Ramos de Souza Janones
Powered by Rock Convert

Neste artigo, dois exemplos práticos de como pegar a cor predominante de uma imagem e aplicar em seu site ou aplicativo utilizando Javascript.

Exemplo JavaSctpt 1

O seguinte código monta um objeto contendo o histograma e recupera a cor mais comum usando um elemento canvas invisível:

//carrega uma imagem
var img = new Image();
img.src = ...
//cria um canvas invisível
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d');
//desenha a imagem no canvas
context.drawImage(img, , );
//recupera vetor de cores
var map = context.getImageData(, , img.width, img.height).data;
//monta histograma
var hex, r,g,b; //,alpha;
var histograma = {};
for (var i = , len = map.length; i < len; i += 4) {
//recupera componentes de um ponto
r = arredonda(map[i]);
g = arredonda(map[i+1]);
b = arredonda(map[i+2]);
//alpha = map[i+2]; //ignora canal alpha
//valor em hexadecimal
hex = rgbToHex(r, g, b);
//adiciona no histograma ou incrementa se já existir
if (histograma[hex] === undefined) {
histograma[hex] = 1;
} else {
histograma[hex]++;
}
}
//recupera cor mais comum
var corMaisComum = null;
var frequenciaCorMaisComum = ;
for (var cor in histograma) {
if (frequenciaCorMaisComum < histograma[cor]) {
corMaisComum = cor;
frequenciaCorMaisComum = histograma[cor];
}
}
console.log(corMaisComum);

O histograma nada mais é do que um tipo de mapa onde a chave é a cor em notação hexadecimal e o valor é a frequência com que a mesma ocorre na imagem.

Nesse algoritmo, usei a função arredonda ao recuperar a cor para arredondá-la para o múltiplo de 5 mais próximo. Dessa forma, pequenas variações na cor não irão atrapalhar o resultado final.

Note que com p histograma não somente podemos obter a cor mais comum, mas também as primeiras N cores mais comuns. Para isso teríamos apenas que criar um vetor com as cores ordenado pela frequência.

LEIA TAMBÉM:  9 benefícios da transição para o Scrum

O código anterior pode ser visto executanto no site jsdo.it, mas postarei o mesmo completo, caso se torne inacessível um dia:

Como vender Software - Seja desktop, web ou MobilePowered by Rock Convert
//"arredonda" o número para o múltiplo de 5 mais próximo
//isso adiciona uma certa tolerância para os tons próximos
function arredonda(v) {
return 5 * (Math.round(v / 5));
}
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
//carrega uma imagem
var img = new Image();
img.src = 'http://jsrun.it/assets/8/O/3/U/8O3Ux.jpg';
img.onload = function() {
$(document.body).append(img);
//cria um canvas invisível
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d');
//desenha a imagem no canvas
context.drawImage(img, , );
//recupera vetor de cores
var map = context.getImageData(, , img.width, img.height).data;
var hex, r,g,b; //,alpha;
var histograma = {};
for (var i = , len = map.length; i < len; i += 4) {
//recupera componentes de um ponto
r = arredonda(map[i]);
g = arredonda(map[i+1]);
b = arredonda(map[i+2]);
//alpha = map[i+2]; //ignora canal alpha
//valor em hexadecimal
hex = rgbToHex(r, g, b);
//adiciona no histograma ou incrementa se já existir
if (histograma[hex] === undefined) {
histograma[hex] = 1;
} else {
histograma[hex]++;
}
}
//recupera cor mais comum
var corMaisComum = null;
var frequenciaCorMaisComum = ;
for (var cor in histograma) {
if (frequenciaCorMaisComum < histograma[cor]) {
corMaisComum = cor;
frequenciaCorMaisComum = histograma[cor];
}
}
console.log(corMaisComum);
//adiciona um div como exemplo
$(document.body).append(
$('<div>').css({
'background-color': corMaisComum,
'width': '200px',
'height': '200px',
'border': '1px solid #000'
})
);
};

O resultado visual fica como na imagem abaixo:

LEIA TAMBÉM:  36 sites para você encontrar trabalho remoto

resultado com a cor retornada

Exemplo JavaScript 2

Você pode utilizar da tecnologia Canvas que é contida nos navegadores que suportam HTML5(atualmente a maioria), e com ele você pode fazer uma função JavaScript que recebe como parâmetro sua imagem e verifica de 5 em 5 pixels qual a determinada cor, e verifica na imagem inteira, e então a cor predominante é setada via R,G,B(red,green,blue) no fundo de sua página.

HTML Exemplar seria:

<span> Background é setado para a cor predominante desta imagem: </span>
<img id="i" src="data:image/jpeg;base64,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
BhSLCA6lqWSpRuTC0Uho6Gto0j//2Q=="/>

Obs: Converti sua imagem em  🙂

E a função que faz a mágica seria esta:

    var rgb = getAverageRGB(document.getElementById('i'));
document.body.style.backgroundColor = 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';
function getAverageRGB(imgEl) {
var blockSize = 5, //checa a cor à cada 5 pixels
defaultRGB = {r:,g:,b:}, // para browsers com incompatibilidade
canvas = document.createElement('canvas'),
context = canvas.getContext && canvas.getContext('2d'),
data, width, height,
i = -4,
length,
rgb = {r:,g:,b:},
count = ; //zera o contador
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, , ); //desenha a imagem cria o canvas
try {
data = context.getImageData(, , width, height);
} catch(e) {
/* gera um erro de segurança, se a imagem for de dominio diferente */alert('x');
return defaultRGB;//retorna  a cor padrão
}
length = data.data.length; //tamanho do array dos dados da imagem
while ( (i += blockSize * 4) < length ) {
++count; //incrementa o contador previamente zerado
rgb.r += data.data[i];
rgb.g += data.data[i+1];
rgb.b += data.data[i+2];
}
// ~~ usado para arrendondar valores para baixo
rgb.r = ~~(rgb.r/count);
rgb.g = ~~(rgb.g/count);
rgb.b = ~~(rgb.b/count);
return rgb;
}

Exemplo funcionando no JSFiddle com sua imagem.

 

Powered by Rock Convert
Siga os bons!
Últimos posts por Ramos de Souza Janones (exibir todos)
vote
Article Rating
LEIA TAMBÉM:  9 Conhecimentos essenciais para profissionais de BI