big-moving.ru/api/soft/picozu/histogram.js.1

152 lines
4.1 KiB
Groff
Executable File

/**
* 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)
];
}