152 lines
4.1 KiB
Groff
152 lines
4.1 KiB
Groff
|
/**
|
||
|
* Part of Picozu Image Editing application.
|
||
|
* Visit https://www.picozu.com for more info.
|
||
|
* The code is copyrighted by Picozu <www.picozu.com>.
|
||
|
*
|
||
|
* @version 1.1.121413
|
||
|
* @package Workers
|
||
|
* @application Picozu <www.picozu.com>
|
||
|
* @license www.picozu.com/license
|
||
|
*/
|
||
|
|
||
|
self.addEventListener('message', function (e) {
|
||
|
function process(data) {
|
||
|
data.type = (typeof data.type != 'undefined') ? data.type : 'rgb';
|
||
|
return {
|
||
|
histogram: calculate(data.type, data.imageData.data),
|
||
|
type: data.type
|
||
|
}
|
||
|
}
|
||
|
self.postMessage(process(e.data));
|
||
|
}, false);
|
||
|
|
||
|
function calculate(type, imgData) {
|
||
|
var chans = [[]];
|
||
|
var maxCount = 0;
|
||
|
var val;
|
||
|
var subtypes = [type];
|
||
|
if (type === 'rgb') {
|
||
|
chans = [
|
||
|
[],
|
||
|
[],
|
||
|
[]
|
||
|
];
|
||
|
subtypes = [
|
||
|
'red',
|
||
|
'green',
|
||
|
'blue'
|
||
|
];
|
||
|
}
|
||
|
else if (type === 'cmyk') {
|
||
|
chans = [
|
||
|
[],
|
||
|
[],
|
||
|
[],
|
||
|
[]
|
||
|
];
|
||
|
subtypes = [
|
||
|
'cyan',
|
||
|
'magenta',
|
||
|
'yellow',
|
||
|
'kelvin'
|
||
|
];
|
||
|
}
|
||
|
var step = 4;
|
||
|
for (var i = 0, n = imgData.length; i < n; i += step) {
|
||
|
if (type === 'rgb' || type === 'red' || type === 'green' || type === 'blue') {
|
||
|
val = [imgData[i], imgData[i + 1], imgData[i + 2]];
|
||
|
}
|
||
|
else if (type === 'cmyk' || type === 'cyan' || type === 'magenta' || type === 'yellow' || type === 'kelvin') {
|
||
|
val = rgb2cmyk(imgData[i], imgData[i + 1], imgData[i + 2]);
|
||
|
}
|
||
|
else if (type === 'hue' || type === 'sat' || type === 'val') {
|
||
|
val = rgb2hsv(imgData[i], imgData[i + 1], imgData[i + 2]);
|
||
|
}
|
||
|
if (type === 'red' || type === 'hue' || type === 'cyan') {
|
||
|
val = [val[0]];
|
||
|
}
|
||
|
else if (type === 'green' || type === 'sat' || type === 'magenta') {
|
||
|
val = [val[1]];
|
||
|
}
|
||
|
else if (type === 'blue' || type === 'val' || type === 'yellow') {
|
||
|
val = [val[2]];
|
||
|
}
|
||
|
else if (type === 'kelvin') {
|
||
|
val = [val[3]];
|
||
|
}
|
||
|
for (var y = 0, m = val.length; y < m; y++) {
|
||
|
if (val[y] in chans[y]) {
|
||
|
chans[y][val[y]]++;
|
||
|
}
|
||
|
else {
|
||
|
chans[y][val[y]] = 1;
|
||
|
}
|
||
|
if (chans[y][val[y]] > maxCount) {
|
||
|
maxCount = chans[y][val[y]];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (maxCount === 0) {
|
||
|
return null;
|
||
|
}
|
||
|
else {
|
||
|
return {
|
||
|
subtypes: subtypes,
|
||
|
chans: chans,
|
||
|
maxCount: maxCount
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function rgb2hsv(red, green, blue) {
|
||
|
red /= 255;
|
||
|
green /= 255;
|
||
|
blue /= 255;
|
||
|
var hue, sat, val, min = Math.min(red, green, blue), max = Math.max(red, green, blue), delta = max - min, val = max;
|
||
|
if (delta === 0) {
|
||
|
hue = sat = 0;
|
||
|
}
|
||
|
else {
|
||
|
sat = delta / max;
|
||
|
if (max === red) {
|
||
|
hue = (green - blue) / delta;
|
||
|
}
|
||
|
else if (max === green) {
|
||
|
hue = (blue - red) / delta + 2;
|
||
|
}
|
||
|
else if (max === blue) {
|
||
|
hue = (red - green) / delta + 4;
|
||
|
}
|
||
|
hue /= 6;
|
||
|
if (hue < 0) {
|
||
|
hue += 1;
|
||
|
}
|
||
|
}
|
||
|
return [
|
||
|
Math.round(hue * 255),
|
||
|
Math.round(sat * 255),
|
||
|
Math.round(val * 255)
|
||
|
];
|
||
|
}
|
||
|
|
||
|
function rgb2cmyk(red, green, blue) {
|
||
|
var cyan = 1 - red / 255;
|
||
|
var magenta = 1 - green / 255;
|
||
|
var yellow = 1 - blue / 255;
|
||
|
var black = Math.min(cyan, magenta, yellow, 1);
|
||
|
if (black === 1) {
|
||
|
cyan = magenta = yellow = 0;
|
||
|
}
|
||
|
else {
|
||
|
var w = 1 - black;
|
||
|
cyan = (cyan - black) / w;
|
||
|
magenta = (magenta - black) / w;
|
||
|
yellow = (yellow - black) / w;
|
||
|
}
|
||
|
return [
|
||
|
Math.round(cyan * 255),
|
||
|
Math.round(magenta * 255),
|
||
|
Math.round(yellow * 255),
|
||
|
Math.round(black * 255)
|
||
|
];
|
||
|
}
|