132 votes

Obtenir la couleur moyenne d'une image via Javascript

Je ne suis pas sûr que ce soit possible, mais je cherche à écrire un script qui renverrait la moyenne. hex o rgb pour une image. Je sais que cela peut être fait en AS mais je cherche à le faire en JavaScript.

24 votes

Mon ami Boaz a déjà emprunté cette voie (j'espère qu'il nous dira ce qu'il en pense) mais la moyenne vous laisse généralement avec une couleur semblable au vomi. Ce que vous voulez vraiment, c'est une "couleur dominante". Il y a plusieurs façons de l'obtenir (histogramme de la teinte avec répartition dynamique, etc.) mais je pense que c'est probablement plus précis pour le résultat que tu veux obtenir.

8voto

350D Points 457

Un moyen moins précis mais plus rapide d'obtenir la couleur moyenne de l'image avec datauri soutien :

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);
}

3 votes

Tout est parfait mais la dernière ligne devrait être context.getImageData(0, 0, 1, 1).data.slice(0,3) pour lire le seul pixel.

6voto

bgreater Points 316

Je suis récemment tombé sur un plugin jQuery qui fait ce que je voulais initialement https://github.com/briangonzalez/jquery.adaptive-backgrounds.js en ce qui concerne l'obtention d'une couleur dominante à partir d'une image.

5voto

luek baja Points 1130

EDIT : Ce n'est qu'après avoir posté ce message que j'ai réalisé que la réponse de @350D faisait exactement la même chose.

Étonnamment, cela peut être fait en seulement 4 lignes de code :

const canvas = document.getElementById("canvas"),
  preview = document.getElementById("preview"),
  ctx = canvas.getContext("2d");

canvas.width = 1;
canvas.height = 1;

preview.width = 400;
preview.height = 400;

function getDominantColor(imageObject) {
  //draw the image to one pixel and let the browser find the dominant color
  ctx.drawImage(imageObject, 0, 0, 1, 1);

  //get pixel color
  const i = ctx.getImageData(0, 0, 1, 1).data;

  console.log(`rgba(${i[0]},${i[1]},${i[2]},${i[3]})`);

  console.log("#" + ((1 << 24) + (i[0] << 16) + (i[1] << 8) + i[2]).toString(16).slice(1));
}

// vvv all of this is to just get the uploaded image vvv
const input = document.getElementById("input");
input.type = "file";
input.accept = "image/*";

input.onchange = event => {
  const file = event.target.files[0];
  const reader = new FileReader();

  reader.onload = readerEvent => {
    const image = new Image();
    image.onload = function() {
      //shows preview of uploaded image
      preview.getContext("2d").drawImage(
        image,
        0,
        0,
        preview.width,
        preview.height,
      );
      getDominantColor(image);
    };
    image.src = readerEvent.target.result;
  };
  reader.readAsDataURL(file, "UTF-8");
};

canvas {
  width: 200px;
  height: 200px;
  outline: 1px solid #000000;
}

<canvas id="preview"></canvas>
<canvas id="canvas"></canvas>
<input id="input" type="file" />

Comment cela fonctionne :

Créer le contexte de la toile

const context = document.createElement("canvas").getContext("2d");

L'image ne sera dessinée que sur un seul pixel de la toile, ce qui permettra au navigateur de trouver la couleur dominante à votre place.

context.drawImage(imageObject, 0, 0, 1, 1);

Après cela, il suffit de récupérer les données de l'image pour le pixel :

const i = context.getImageData(0, 0, 1, 1).data;

Enfin, convertissez en rgba o HEX :

const rgba = `rgba(${i[0]},${i[1]},${i[2]},${i[3]})`;

const HEX = "#" + ((1 << 24) + (i[0] << 16) + (i[1] << 8) + i[2]).toString(16).slice(1);

Il y a cependant un problème avec cette méthode, et c'est que getImageData provoquera parfois des erreurs Unable to get image data from canvas because the canvas has been tainted by cross-origin data. C'est la raison pour laquelle vous devez télécharger des images dans la démo au lieu de saisir une URL, par exemple.

Cette méthode peut également être utilisée pour la pixellisation des images en augmentant la largeur et la hauteur pour dessiner l'image.

Cela fonctionne sur chrome mais peut ne pas fonctionner sur d'autres navigateurs.

4voto

Joel Martinez Points 22924

Javascript n'a pas accès aux données de couleur des pixels individuels d'une image. Du moins, pas avant html5 ... à ce moment-là, il est logique que vous puissiez dessiner une image sur un canevas, puis inspecter le canevas (peut-être, je ne l'ai jamais fait moi-même).

3voto

Grant Miller Points 6261

Solution tout-en-un

Personnellement, je combinerais Voleur de couleurs avec ceci version modifiée de Nommez cette couleur pour obtenir un ensemble plus que suffisant de résultats de couleurs dominantes pour les images.

Exemple :

Considérez l'image suivante :

enter image description here

Vous pouvez utiliser le code suivant pour extraire les données de l'image relatives à la couleur 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;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X