Je ne suis pas sûr que cela soit possible, mais je cherche à écrire un script qui renverrait la moyenne hex
ou la rgb
valeur d'une image. Je sais que cela peut être fait en AS, mais je cherche à le faire en JavaScript.
Je ne suis pas sûr que cela soit possible, mais je cherche à écrire un script qui renverrait la moyenne hex
ou la rgb
valeur d'une image. Je sais que cela peut être fait en AS, mais je cherche à le faire en JavaScript.
Réponses:
AFAIK, la seule façon de le faire est avec <canvas/>
...
DÉMO V2 : http://jsfiddle.net/xLF38/818/
Notez que cela ne fonctionnera qu'avec les images du même domaine et dans les navigateurs prenant en charge le canevas 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;
}
Pour IE, consultez les excanvas .
'rgb('+rgb.r+','+rgb.b+','+rgb.g+')'
et cela devrait être 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')'
. c'est étrange quand la couleur dominante est le bleu mais le résultat est vert :).
img.crossOrigin = '';
avant de définir l' src
attribut. Trouvée sur: coderwall.com/p/pa-2uw
count === length / 4 / blockSize
;)
Je pensais que je publierais un projet que j'ai récemment rencontré pour obtenir une couleur dominante:
Un script pour saisir la couleur dominante ou une palette de couleurs représentative d'une image. Utilise javascript et canvas.
Les autres solutions mentionnant et suggérant la couleur dominante ne répondent jamais vraiment à la question dans le bon contexte ("en javascript"). Espérons que ce projet aidera ceux qui veulent faire exactement cela.
"Dominant Color" est délicat. Ce que vous voulez faire, c'est comparer la distance entre chaque pixel et tous les autres pixels de l'espace colorimétrique (distance euclidienne), puis trouver le pixel dont la couleur est la plus proche de toutes les autres couleurs. Ce pixel est la couleur dominante. La couleur moyenne sera généralement de la boue.
J'aurais aimé avoir MathML ici pour vous montrer la distance euclidienne. Recherche le sur Google.
J'ai effectué l'exécution ci-dessus dans l'espace colorimétrique RVB en utilisant PHP / GD ici: https://gist.github.com/cf23f8bddb307ad4abd8
Ceci est cependant très coûteux en calcul. Il plantera votre système sur de grandes images et plantera définitivement votre navigateur si vous l'essayez dans le client. J'ai travaillé sur la refactorisation de mon exécution pour: - stocker les résultats dans une table de recherche pour une utilisation future dans l'itération sur chaque pixel. - pour diviser de grandes images en grilles de 20px 20px pour une dominance localisée. - utiliser la distance euclidienne entre x1y1 et x1y2 pour déterminer la distance entre x1y1 et x1y3.
Veuillez me faire savoir si vous faites des progrès sur ce front. Je serais heureux de le voir. Je vais faire la même chose.
Canvas est certainement le meilleur moyen de le faire chez le client. SVG ne l'est pas, SVG est basé sur des vecteurs. Une fois l'exécution terminée, la prochaine chose que je veux faire est de faire fonctionner cela dans le canevas (peut-être avec un webworker pour le calcul de la distance globale de chaque pixel).
Une autre chose à laquelle il faut penser est que RVB n'est pas un bon espace colorimétrique pour faire cela, car la distance euclidienne entre les couleurs dans l'espace RVB n'est pas très proche de la distance visuelle. Un meilleur espace colorimétrique pour faire cela pourrait être LUV, mais je n'ai pas trouvé de bonne bibliothèque pour cela, ni d'algorithmes pour convertir RVB en LUV.
Une approche entièrement différente consisterait à trier vos couleurs dans un arc-en-ciel et à créer un histogramme avec une tolérance pour tenir compte des différentes nuances d'une couleur. Je n'ai pas essayé cela, car le tri des couleurs dans un arc-en-ciel est difficile, tout comme les histogrammes de couleurs. Je pourrais essayer ceci ensuite. Encore une fois, faites-moi savoir si vous faites des progrès ici.
Premièrement: cela peut être fait sans HTML5 Canvas ou SVG.
En fait, quelqu'un a juste réussi à générer des fichiers PNG côté client en utilisant JavaScript , sans canevas ni SVG, en utilisant le schéma d'URI de données .
Deuxièmement: vous n'aurez peut-être pas besoin du tout de Canvas, SVG ou de tout ce qui précède.
Si vous avez seulement besoin de traiter les images côté client, sans les modifier, tout cela n'est pas nécessaire.
Vous pouvez obtenir l'adresse source à partir de la balise img sur la page, lui faire une requête XHR - elle proviendra probablement du cache du navigateur - et la traiter comme un flux d'octets à partir de Javascript.
Vous aurez besoin d'une bonne compréhension du format d'image. (Le générateur ci-dessus est partiellement basé sur des sources libpng et pourrait fournir un bon point de départ.)
Je dirais via la balise HTML canvas.
Vous pouvez trouver ici un article de @Georg parlant d'un petit code du développeur 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);
Cela inverse l'image en utilisant les valeurs R, V et B de chaque pixel. Vous pouvez facilement stocker les valeurs RVB, puis arrondir les tableaux rouge, vert et bleu, et enfin les reconvertir en un code HEX.
Je suis récemment tombé sur un plugin jQuery qui fait ce que je voulais à l'origine https://github.com/briangonzalez/jquery.adaptive-backgrounds.js en ce qui concerne l'obtention d'une couleur dominante à partir d'une image.
Javascript n'a pas accès aux données de couleur des pixels individuels d'une image. Au moins, peut-être pas avant html5 ... à quel point il va de soi que vous serez capable de dessiner une image sur une toile, puis d'inspecter la toile (peut-être que je ne l'ai jamais fait moi-même).
Personnellement, je combinerais Color Thief avec cette version modifiée de Name that Color pour obtenir un éventail plus que suffisant de résultats de couleurs dominantes pour les images.
Exemple:
Considérez l'image suivante:
Vous pouvez utiliser le code suivant pour extraire les données d'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;
Il s'agit de la "Quantification des couleurs" qui a plusieurs approches comme MMCQ (Quantification Médiane Modifiée) ou OQ (Quantification Octree). Différentes approches utilisent des K-Means pour obtenir des groupes de couleurs.
J'ai tout rassemblé ici, depuis que je cherchais une solution tvOS
là où il y a un sous-ensemble de XHTML, qui n'a pas<canvas/>
élément:
Générer les couleurs dominantes pour une image RVB avec XMLHttpRequest
Moyen moins précis mais le plus rapide d'obtenir une couleur moyenne de l'image avec datauri
support:
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);
}
Il existe un outil en ligne pickimagecolor.com qui vous aide à trouver la couleur moyenne ou dominante de l'image, il vous suffit de télécharger une image depuis votre ordinateur puis de cliquer sur l'image. Il donne la couleur moyenne en HEX, RVB et HSV. Il trouve également les nuances de couleur correspondant à cette couleur à choisir. Je l'ai utilisé plusieurs fois.