image-js
Version:
Image processing and manipulation in JavaScript
83 lines (81 loc) • 2.95 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = grey;
var _clamp = require("../internal/clamp");
var _getOutputImage = require("../internal/getOutputImage");
var _model = require("../model/model");
var _greyAlgorithms = require("./greyAlgorithms");
/**
* Call back that converts the RGB channels to grey. It will be clamped after.
* @callback GreyAlgorithmCallback
* @param {number} red - value of the red channel
* @param {number} green - value of the green channel
* @param {number} blue - value of the blue channel
* @return {number} value of the grey channel
*/
/**
* Converts the current image to greyscale.
* The source image has to be RGB.
* If there is an alpha channel we need to decide what to do:
* * keepAlpha : we will keep the alpha channel and you will get a GREY / A image
* * mergeAlpha : we will multiply each pixel of the image by the alpha
* @memberof Image
* @instance
* @param {object} [options]
* @param {GreyAlgorithm|GreyAlgorithmCallback} [options.algorithm='luma709'] - Algorithm to get the grey value from RGB values
* @param {boolean} [options.keepAlpha=false] - If true, the RGB values are treated
* separately from the alpha channel and the method returns a GREYA image.
* @param {boolean} [options.mergeAlpha=true] - If true, the alpha channel will be used to scale the grey pixel.
* @param {Image} [options.out]
* @return {Image}
*/
function grey(options = {}) {
let {
algorithm = 'luma709',
keepAlpha = false,
mergeAlpha = true
} = options;
if (typeof algorithm !== 'string' && typeof algorithm !== 'function') {
throw new TypeError('algorithm must be a string or a function');
}
this.checkProcessable('grey', {
bitDepth: [8, 16],
alpha: [0, 1]
});
if (this.components === 1) {
algorithm = 'red'; // actually we just take the first channel if it is a grey image
}
keepAlpha &= this.alpha;
mergeAlpha &= this.alpha;
if (keepAlpha) {
mergeAlpha = false;
}
let newImage = (0, _getOutputImage.getOutputImage)(this, options, {
components: 1,
alpha: keepAlpha,
colorModel: _model.GREY
});
let method;
if (typeof algorithm === 'function') {
method = algorithm;
} else {
method = _greyAlgorithms.methods[algorithm.toLowerCase()];
if (!method) {
throw new Error(`unsupported grey algorithm: ${algorithm}`);
}
}
let ptr = 0;
for (let i = 0; i < this.data.length; i += this.channels) {
if (mergeAlpha) {
newImage.data[ptr++] = (0, _clamp.clamp)(method(this.data[i], this.data[i + 1], this.data[i + 2], this) * this.data[i + this.components] / this.maxValue, this);
} else {
newImage.data[ptr++] = (0, _clamp.clamp)(method(this.data[i], this.data[i + 1], this.data[i + 2], this), this);
if (newImage.alpha) {
newImage.data[ptr++] = this.data[i + this.components];
}
}
}
return newImage;
}