Non sono sicuro che sia possibile, ma sto cercando di scrivere uno script che restituisca la media hex
o il rgb
valore per un'immagine. So che può essere fatto in AS ma sto cercando di farlo in JavaScript.
Non sono sicuro che sia possibile, ma sto cercando di scrivere uno script che restituisca la media hex
o il rgb
valore per un'immagine. So che può essere fatto in AS ma sto cercando di farlo in JavaScript.
Risposte:
AFAIK, l'unico modo per farlo è con <canvas/>
...
DEMO V2 : http://jsfiddle.net/xLF38/818/
Nota, questo funzionerà solo con le immagini sullo stesso dominio e nei browser che supportano HTML5 canvas:
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;
}
Per IE, controlla excanvas .
'rgb('+rgb.r+','+rgb.b+','+rgb.g+')'
e dovrebbe essere 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')'
. è strano quando il colore dominante è il blu ma il risultato è il verde :).
img.crossOrigin = '';
prima di impostare l' src
attributo. Trovato su: coderwall.com/p/pa-2uw
count === length / 4 / blockSize
;)
Ho pensato di pubblicare un progetto che ho incontrato di recente per ottenere un colore dominante:
Un copione per catturare il colore dominante o una tavolozza di colori rappresentativa da un'immagine. Utilizza javascript e canvas.
Le altre soluzioni che menzionano e suggeriscono il colore dominante non rispondono mai veramente alla domanda nel giusto contesto ("in javascript"). Speriamo che questo progetto aiuti coloro che vogliono fare proprio questo.
"Dominant Color" è complicato. Quello che vuoi fare è confrontare la distanza tra ogni pixel e ogni altro pixel nello spazio colore (distanza euclidea), quindi trovare il pixel il cui colore è più vicino a ogni altro colore. Quel pixel è il colore dominante. Il colore medio sarà solitamente fango.
Vorrei avere qui il MathML per mostrarvi la distanza euclidea. Google.
Ho completato l'esecuzione di cui sopra nello spazio colore RGB utilizzando PHP / GD qui: https://gist.github.com/cf23f8bddb307ad4abd8
Questo tuttavia è molto costoso dal punto di vista computazionale. Si bloccherà il tuo sistema su immagini di grandi dimensioni e sicuramente bloccherà il browser se lo provi nel client. Ho lavorato al refactoring della mia esecuzione per: - memorizzare i risultati in una tabella di ricerca per un uso futuro nell'iterazione su ogni pixel. - per dividere immagini di grandi dimensioni in griglie di 20px 20px per dominanza localizzata. - utilizzare la distanza euclidea tra x1y1 e x1y2 per calcolare la distanza tra x1y1 e x1y3.
Per favore fatemi sapere se fate progressi su questo fronte. Sarei felice di vederlo. Farò lo stesso.
La tela è sicuramente il modo migliore per farlo nel client. SVG non lo è, SVG è basato su vettori. Dopo aver interrotto l'esecuzione, la prossima cosa che voglio fare è farlo funzionare nell'area di disegno (magari con un webworker per il calcolo della distanza complessiva di ogni pixel).
Un'altra cosa a cui pensare è che RGB non è un buon spazio colore per fare questo, perché la distanza euclidea tra i colori nello spazio RGB non è molto vicina alla distanza visiva. Uno spazio colore migliore per fare questo potrebbe essere LUV, ma non ho trovato una buona libreria per questo, o alcun algoritmo per convertire RGB in LUV.
Un approccio completamente diverso sarebbe ordinare i colori in un arcobaleno e costruire un istogramma con tolleranza per tenere conto delle diverse sfumature di un colore. Non l'ho provato, perché ordinare i colori in un arcobaleno è difficile, così come gli istogrammi dei colori. Potrei provare questo dopo. Di nuovo, fammi sapere se fai progressi qui.
Primo: può essere fatto senza HTML5 Canvas o SVG.
In realtà, qualcuno è appena riuscito a generare file PNG lato client utilizzando JavaScript , senza canvas o SVG, utilizzando lo schema URI dei dati .
Secondo: potresti non aver bisogno di Canvas, SVG o nessuno dei precedenti.
Se hai solo bisogno di elaborare le immagini sul lato client, senza modificarle, tutto ciò non è necessario.
Puoi ottenere l'indirizzo sorgente dal tag img sulla pagina, fare una richiesta XHR per esso - molto probabilmente proverrà dalla cache del browser - ed elaborarlo come flusso di byte da Javascript.
Avrai bisogno di una buona conoscenza del formato dell'immagine. (Il generatore di cui sopra è parzialmente basato su sorgenti libpng e potrebbe fornire un buon punto di partenza.)
Direi tramite il tag HTML canvas.
Puoi trovare qui un post di @Georg che parla di un piccolo codice dello sviluppatore di 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);
Questo inverte l'immagine usando il valore R, G e B di ogni pixel. È possibile memorizzare facilmente i valori RGB, quindi arrotondare gli array rosso, verde e blu e infine riconvertirli in un codice HEX.
Recentemente mi sono imbattuto in un plugin jQuery che fa quello che volevo originariamente https://github.com/briangonzalez/jquery.adaptive-backgrounds.js per quanto riguarda l'ottenimento di un colore dominante da un'immagine.
Javascript non ha accesso ai dati di colore dei singoli pixel di un'immagine. Almeno, non forse fino a html5 ... a quel punto è logico che sarai in grado di disegnare un'immagine su una tela e poi ispezionare la tela (forse, non l'ho mai fatto io stesso).
Combinerei personalmente Color Thief insieme a questa versione modificata di Name that Color per ottenere una gamma più che sufficiente di risultati cromatici dominanti per le immagini.
Esempio:
Considera la seguente immagine:
È possibile utilizzare il seguente codice per estrarre i dati dell'immagine relativi al colore 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;
Si tratta di "Quantizzazione del colore" che ha diversi approcci come MMCQ (Quantization Median Cut Modificato) o OQ (Quantizzazione Octree). Un approccio diverso utilizza K-Means per ottenere grappoli di colori.
Ho messo tutti insieme qui, poiché stavo trovando una soluzione per tvOS
dove c'è un sottoinsieme di XHTML, che non ha <canvas/>
elementi:
Genera i colori dominanti per un'immagine RGB con XMLHttpRequest
Modo meno accurato ma più veloce per ottenere il colore medio dell'immagine con datauri
supporto:
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);
}
C'è uno strumento online pickimagecolor.com che ti aiuta a trovare il colore medio o dominante dell'immagine. Devi solo caricare un'immagine dal tuo computer e quindi fare clic sull'immagine. Fornisce il colore medio in HEX, RGB e HSV. Trova anche le sfumature di colore corrispondenti a quel colore tra cui scegliere. L'ho usato più volte.