Ich bin mir nicht sicher, ob dies möglich ist, aber ich möchte ein Skript schreiben, das den Durchschnitt hex
oder rgb
Wert für ein Bild zurückgibt. Ich weiß, dass es in AS gemacht werden kann, aber ich möchte es in JavaScript machen.
Ich bin mir nicht sicher, ob dies möglich ist, aber ich möchte ein Skript schreiben, das den Durchschnitt hex
oder rgb
Wert für ein Bild zurückgibt. Ich weiß, dass es in AS gemacht werden kann, aber ich möchte es in JavaScript machen.
Antworten:
AFAIK, der einzige Weg dies zu tun ist mit <canvas/>
...
DEMO V2 : http://jsfiddle.net/xLF38/818/
Beachten Sie, dass dies nur mit Bildern in derselben Domäne und in Browsern funktioniert, die HTML5-Canvas unterstützen:
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;
}
Schauen Sie sich für IE excanvas an .
'rgb('+rgb.r+','+rgb.b+','+rgb.g+')'
und das sollte sein 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')'
. Es ist seltsam, wenn die dominierende Farbe blau ist, aber das Ergebnis ist grün :).
img.crossOrigin = '';
bevor Sie das src
Attribut festlegen. Gefunden auf: coderwall.com/p/pa-2uw
count === length / 4 / blockSize
;)
Ich dachte, ich würde ein Projekt veröffentlichen, auf das ich kürzlich gestoßen bin, um eine dominante Farbe zu erhalten:
Ein Skript zum Abrufen der dominanten Farbe oder einer repräsentativen Farbpalette aus einem Bild. Verwendet Javascript und Canvas.
Die anderen Lösungen, die dominante Farben erwähnen und vorschlagen, beantworten die Frage nie wirklich im richtigen Kontext ("in Javascript"). Hoffentlich hilft dieses Projekt denen, die genau das wollen.
"Dominante Farbe" ist schwierig. Sie möchten den Abstand zwischen jedem Pixel und jedem anderen Pixel im Farbraum (euklidischer Abstand) vergleichen und dann das Pixel finden, dessen Farbe jeder anderen Farbe am nächsten kommt. Dieses Pixel ist die dominierende Farbe. Die durchschnittliche Farbe ist normalerweise Schlamm.
Ich wünschte, ich hätte MathML hier, um Ihnen die euklidische Entfernung zu zeigen. Google es.
Ich habe die obige Ausführung im RGB-Farbraum mit PHP / GD hier durchgeführt: https://gist.github.com/cf23f8bddb307ad4abd8
Dies ist jedoch sehr rechenintensiv. Es wird Ihr System bei großen Bildern zum Absturz bringen und Ihren Browser definitiv zum Absturz bringen, wenn Sie es im Client versuchen. Ich habe daran gearbeitet, meine Ausführung zu überarbeiten, um: - Ergebnisse in einer Nachschlagetabelle für die zukünftige Verwendung in der Iteration über jedes Pixel zu speichern. - Aufteilen großer Bilder in Raster von 20 x 20 Pixel für eine lokalisierte Dominanz. - den euklidischen Abstand zwischen x1y1 und x1y2 verwenden, um den Abstand zwischen x1y1 und x1y3 zu ermitteln.
Bitte lassen Sie mich wissen, wenn Sie in dieser Hinsicht Fortschritte machen. Ich würde mich freuen, es zu sehen. Ich werde dasselbe tun.
Canvas ist definitiv der beste Weg, dies im Client zu tun. SVG ist nicht, SVG ist vektorbasiert. Nachdem ich die Ausführung beendet habe, möchte ich sie als Nächstes auf der Leinwand zum Laufen bringen (möglicherweise mit einem Webworker für die Berechnung der Gesamtentfernung jedes Pixels).
Eine andere Sache, über die man nachdenken sollte, ist, dass RGB kein guter Farbraum dafür ist, da der euklidische Abstand zwischen Farben im RGB-Raum nicht sehr nahe am visuellen Abstand liegt. Ein besserer Farbraum dafür könnte LUV sein, aber ich habe keine gute Bibliothek dafür gefunden oder irgendwelche Algorithmen für die Konvertierung von RGB in LUV.
Ein völlig anderer Ansatz wäre, Ihre Farben in einem Regenbogen zu sortieren und ein Histogramm mit Toleranz zu erstellen, um unterschiedliche Farbtöne zu berücksichtigen. Ich habe dies nicht versucht, da das Sortieren von Farben in einem Regenbogen schwierig ist, ebenso wie Farbhistogramme. Ich könnte das als nächstes versuchen. Lassen Sie mich noch einmal wissen, ob Sie hier Fortschritte machen.
Erstens: Dies kann ohne HTML5 Canvas oder SVG erfolgen.
Eigentlich jemand einfach zu verwaltender Client-seitige PNG - Dateien mit Hilfe von JavaScript zu generieren , ohne Leinwand oder SVG, die unter Verwendung von Daten - URI - Schema .
Zweitens: Möglicherweise benötigen Sie Canvas, SVG oder eines der oben genannten Elemente überhaupt nicht.
Wenn Sie nur benötigen Prozessbilder auf der Client - Seite, ohne sie zu modifizieren, all dies ist nicht erforderlich.
Sie können die Quelladresse aus dem img-Tag auf der Seite abrufen , eine XHR- Anfrage dafür stellen - sie wird höchstwahrscheinlich aus dem Browser-Cache stammen - und sie als Byte-Stream aus Javascript verarbeiten.
Sie benötigen ein gutes Verständnis des Bildformats. (Der obige Generator basiert teilweise auf libpng-Quellen und bietet möglicherweise einen guten Ausgangspunkt.)
Ich würde über das HTML-Canvas-Tag sagen.
Sie können finden hier einen Beitrag von @Georg sprechen über einen kleinen Code von der Opera dev:
// 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);
Dies invertiert das Bild unter Verwendung des R-, G- und B-Werts jedes Pixels. Sie können die RGB-Werte problemlos speichern, dann die roten, grünen und blauen Arrays aufrunden und sie schließlich wieder in einen HEX-Code konvertieren.
Ich bin kürzlich auf ein jQuery-Plugin gestoßen, das genau das tut, was ich ursprünglich wollte: https://github.com/briangonzalez/jquery.adaptive-backgrounds.js , um eine dominierende Farbe aus einem Bild zu erhalten.
Javascript hat keinen Zugriff auf die einzelnen Pixelfarbdaten eines Bildes. Zumindest nicht bis html5 ... an diesem Punkt liegt es nahe, dass Sie ein Bild auf eine Leinwand zeichnen und dann die Leinwand untersuchen können (vielleicht habe ich es selbst nie gemacht).
Ich persönlich würde Color Thief zusammen mit dieser modifizierten Version von Name that Color kombinieren , um eine mehr als ausreichende Auswahl an dominanten Farbergebnissen für Bilder zu erhalten.
Beispiel:
Betrachten Sie das folgende Bild:
Mit dem folgenden Code können Sie Bilddaten extrahieren, die sich auf die dominante Farbe beziehen:
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;
Hier geht es um " Farbquantisierung ", die verschiedene Ansätze wie MMCQ (Modified Median Cut Quantization) oder OQ (Octree Quantization) hat. Unterschiedliche Ansätze verwenden K-Mittel , um Farbcluster zu erhalten.
Ich habe hier alles zusammen geputtet, da ich eine Lösung für tvOS
eine Teilmenge von XHTML gefunden habe, die kein <canvas/>
Element enthält:
Generieren Sie die dominanten Farben für ein RGB-Bild mit XMLHttpRequest
Weniger genau, aber der schnellste Weg, um mit datauri
Unterstützung die durchschnittliche Farbe des Bildes zu erhalten :
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);
}
Wie in anderen Antworten ausgeführt, ist häufig die dominierende Farbe das, was Sie wirklich wollen, im Gegensatz zu der durchschnittlichen Farbe, die dazu neigt, braun zu sein. Ich habe ein Skript geschrieben, das die häufigste Farbe erhält, und es in diesem Kern veröffentlicht
Es gibt ein Online-Tool pickimagecolor.com , mit dem Sie die durchschnittliche oder dominante Farbe des Bildes ermitteln können. Sie müssen lediglich ein Bild von Ihrem Computer hochladen und dann auf das Bild klicken. Es gibt die durchschnittliche Farbe in HEX, RGB und HSV. Es werden auch die Farbtöne gefunden, die zu dieser Farbe passen, aus der Sie auswählen können. Ich habe es mehrfach benutzt.