mirror of
https://github.com/dawidolko/Website-Templates.git
synced 2025-10-27 07:53:11 +01:00
127 lines
3.5 KiB
JavaScript
127 lines
3.5 KiB
JavaScript
// Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>
|
|
// This work is free. You can redistribute it and/or modify it
|
|
// under the terms of the WTFPL, Version 2
|
|
// For more information see LICENSE.txt or http://www.wtfpl.net/
|
|
//
|
|
// For more information, the home page:
|
|
// http://pieroxy.net/blog/pages/color-finder/index.html
|
|
//
|
|
// Detection of the most prominent color in an image
|
|
// version 1.1.1
|
|
|
|
function ColorFinder(colorFactorCallback) {
|
|
this.callback = colorFactorCallback;
|
|
this.getMostProminentColor = function(imgEl) {
|
|
var rgb = null;
|
|
if (!this.callback) this.callback = function() { return 1; };
|
|
var data = this.getImageData(imgEl);
|
|
rgb = this.getMostProminentRGBImpl(data, 6, rgb, this.callback);
|
|
rgb = this.getMostProminentRGBImpl(data, 4, rgb, this.callback);
|
|
rgb = this.getMostProminentRGBImpl(data, 2, rgb, this.callback);
|
|
rgb = this.getMostProminentRGBImpl(data, 0, rgb, this.callback);
|
|
return rgb;
|
|
};
|
|
|
|
this.getImageData = function(imgEl, degrade, rgbMatch, colorFactorCallback) {
|
|
|
|
var rgb,
|
|
canvas = document.createElement('canvas'),
|
|
context = canvas.getContext && canvas.getContext('2d'),
|
|
data, width, height, key,
|
|
i = -4,
|
|
db={},
|
|
length,r,g,b,
|
|
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 null;
|
|
}
|
|
|
|
length = data.data.length;
|
|
|
|
var factor = Math.max(1,Math.round(length/5000));
|
|
var result = {};
|
|
|
|
while ( (i += 4*factor) < length ) {
|
|
if (data.data[i+3]>32) {
|
|
key = (data.data[i]>>degrade) + "," + (data.data[i+1]>>degrade) + "," + (data.data[i+2]>>degrade);
|
|
if (!result.hasOwnProperty(key)) {
|
|
rgb = {r:data.data[i], g:data.data[i+1], b:data.data[i+2],count:1};
|
|
rgb.weight = this.callback(rgb.r, rgb.g, rgb.b);
|
|
if (rgb.weight<=0) rgb.weight = 1e-10;
|
|
result[key]=rgb;
|
|
} else {
|
|
rgb=result[key];
|
|
rgb.count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
this.getMostProminentRGBImpl = function(pixels, degrade, rgbMatch, colorFactorCallback) {
|
|
|
|
var rgb = {r:0,g:0,b:0,count:0,d:degrade},
|
|
db={},
|
|
pixel,pixelKey,pixelGroupKey,
|
|
length,r,g,b,
|
|
count = 0;
|
|
|
|
|
|
for (pixelKey in pixels) {
|
|
pixel = pixels[pixelKey];
|
|
totalWeight = pixel.weight * pixel.count;
|
|
++count;
|
|
if (this.doesRgbMatch(rgbMatch, pixel.r, pixel.g, pixel.b)) {
|
|
pixelGroupKey = (pixel.r>>degrade) + "," + (pixel.g>>degrade) + "," + (pixel.b>>degrade);
|
|
if (db.hasOwnProperty(pixelGroupKey))
|
|
db[pixelGroupKey]+=totalWeight;
|
|
else
|
|
db[pixelGroupKey]=totalWeight;
|
|
}
|
|
}
|
|
|
|
for (i in db) {
|
|
data = i.split(",");
|
|
r = data[0];
|
|
g = data[1];
|
|
b = data[2];
|
|
count = db[i];
|
|
|
|
if (count>rgb.count) {
|
|
rgb.count = count;
|
|
data = i.split(",");
|
|
rgb.r = r;
|
|
rgb.g = g;
|
|
rgb.b = b;
|
|
}
|
|
}
|
|
|
|
return rgb;
|
|
|
|
};
|
|
|
|
this.doesRgbMatch = function(rgb,r,g,b) {
|
|
if (rgb==null) return true;
|
|
r = r >> rgb.d;
|
|
g = g >> rgb.d;
|
|
b = b >> rgb.d;
|
|
return rgb.r == r && rgb.g == g && rgb.b == b;
|
|
}
|
|
|
|
}
|