-
Notifications
You must be signed in to change notification settings - Fork 7
/
rgbaster.js
120 lines (93 loc) · 3.53 KB
/
rgbaster.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
;(function(window, undefined){
"use strict";
// Helper functions.
var getContext = function(width, height){
var canvas = document.createElement("canvas");
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
return canvas.getContext('2d');
};
var getImageData = function(img, loaded){
var imgObj = new Image();
var imgSrc = img.src || img;
// Can't set cross origin to be anonymous for data url's
// https://github.com/mrdoob/three.js/issues/1305
if ( imgSrc.substring(0,5) !== 'data:' )
imgObj.crossOrigin = "Anonymous";
imgObj.onload = function(){
var context = getContext(imgObj.width, imgObj.height);
context.drawImage(imgObj, 0, 0);
var imageData = context.getImageData(0, 0, imgObj.width, imgObj.height);
loaded && loaded(imageData.data);
};
imgObj.src = imgSrc;
};
var makeRGB = function(name){
return ['rgb(', name, ')'].join('');
};
var mapPalette = function(palette){
var arr = [];
for (var prop in palette) { arr.push( frmtPobj(prop, palette[prop]) ) };
arr.sort(function(a, b) { return (b.count - a.count) });
return arr;
};
var fitPalette = function(arr, fitSize) {
if (arr.length > fitSize ) {
return arr.slice(0,fitSize);
} else {
for (var i = arr.length-1 ; i < fitSize-1; i++) { arr.push( frmtPobj('0,0,0', 0) ) };
return arr;
};
};
var frmtPobj = function(a,b){
return {name: makeRGB(a), count: b};
}
// RGBaster Object
// ---------------
//
var PALETTESIZE = 10;
var RGBaster = {};
RGBaster.colors = function(img, opts){
opts = opts || {};
var exclude = opts.exclude || [ ], // for example, to exclude white and black: [ '0,0,0', '255,255,255' ]
paletteSize = opts.paletteSize || PALETTESIZE;
getImageData(img, function(data){
var colorCounts = {},
rgbString = '',
rgb = [],
colors = {
dominant: { name: '', count: 0 },
palette: []
};
var i = 0;
for (; i < data.length; i += 4) {
rgb[0] = data[i];
rgb[1] = data[i+1];
rgb[2] = data[i+2];
rgbString = rgb.join(",");
// skip undefined data and transparent pixels
if (rgb.indexOf(undefined) !== -1 || data[i + 3] === 0) {
continue;
}
// Ignore those colors in the exclude list.
if ( exclude.indexOf( makeRGB(rgbString) ) === -1 ) {
if ( rgbString in colorCounts ) {
colorCounts[rgbString] = colorCounts[rgbString] + 1;
}
else{
colorCounts[rgbString] = 1;
}
}
}
if ( opts.success ) {
var palette = fitPalette( mapPalette(colorCounts), paletteSize+1 );
opts.success({
dominant: palette[0].name,
secondary: palette[1].name,
palette: palette.map(function(c){ return c.name; }).slice(1)
});
}
});
};
window.RGBaster = window.RGBaster || RGBaster;
})(window);