// Copyright 2013 Lovell Fuller and others. // SPDX-License-Identifier: Apache-2.0 'use strict'; const color = require('color'); const is = require('./is'); /** * Colourspaces. * @private */ const colourspace = { multiband: 'multiband', 'b-w': 'b-w', bw: 'b-w', cmyk: 'cmyk', srgb: 'srgb' }; /** * Tint the image using the provided colour. * An alpha channel may be present and will be unchanged by the operation. * * @example * const output = await sharp(input) * .tint({ r: 255, g: 240, b: 16 }) * .toBuffer(); * * @param {string|Object} tint - Parsed by the [color](https://www.npmjs.org/package/color) module. * @returns {Sharp} * @throws {Error} Invalid parameter */ function tint (tint) { this._setBackgroundColourOption('tint', tint); return this; } /** * Convert to 8-bit greyscale; 256 shades of grey. * This is a linear operation. If the input image is in a non-linear colour space such as sRGB, use `gamma()` with `greyscale()` for the best results. * By default the output image will be web-friendly sRGB and contain three (identical) color channels. * This may be overridden by other sharp operations such as `toColourspace('b-w')`, * which will produce an output image containing one color channel. * An alpha channel may be present, and will be unchanged by the operation. * * @example * const output = await sharp(input).greyscale().toBuffer(); * * @param {Boolean} [greyscale=true] * @returns {Sharp} */ function greyscale (greyscale) { this.options.greyscale = is.bool(greyscale) ? greyscale : true; return this; } /** * Alternative spelling of `greyscale`. * @param {Boolean} [grayscale=true] * @returns {Sharp} */ function grayscale (grayscale) { return this.greyscale(grayscale); } /** * Set the pipeline colourspace. * * The input image will be converted to the provided colourspace at the start of the pipeline. * All operations will use this colourspace before converting to the output colourspace, * as defined by {@link #tocolourspace|toColourspace}. * * This feature is experimental and has not yet been fully-tested with all operations. * * @since 0.29.0 * * @example * // Run pipeline in 16 bits per channel RGB while converting final result to 8 bits per channel sRGB. * await sharp(input) * .pipelineColourspace('rgb16') * .toColourspace('srgb') * .toFile('16bpc-pipeline-to-8bpc-output.png') * * @param {string} [colourspace] - pipeline colourspace e.g. `rgb16`, `scrgb`, `lab`, `grey16` [...](https://github.com/libvips/libvips/blob/41cff4e9d0838498487a00623462204eb10ee5b8/libvips/iofuncs/enumtypes.c#L774) * @returns {Sharp} * @throws {Error} Invalid parameters */ function pipelineColourspace (colourspace) { if (!is.string(colourspace)) { throw is.invalidParameterError('colourspace', 'string', colourspace); } this.options.colourspacePipeline = colourspace; return this; } /** * Alternative spelling of `pipelineColourspace`. * @param {string} [colorspace] - pipeline colorspace. * @returns {Sharp} * @throws {Error} Invalid parameters */ function pipelineColorspace (colorspace) { return this.pipelineColourspace(colorspace); } /** * Set the output colourspace. * By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels. * * @example * // Output 16 bits per pixel RGB * await sharp(input) * .toColourspace('rgb16') * .toFile('16-bpp.png') * * @param {string} [colourspace] - output colourspace e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://github.com/libvips/libvips/blob/3c0bfdf74ce1dc37a6429bed47fa76f16e2cd70a/libvips/iofuncs/enumtypes.c#L777-L794) * @returns {Sharp} * @throws {Error} Invalid parameters */ function toColourspace (colourspace) { if (!is.string(colourspace)) { throw is.invalidParameterError('colourspace', 'string', colourspace); } this.options.colourspace = colourspace; return this; } /** * Alternative spelling of `toColourspace`. * @param {string} [colorspace] - output colorspace. * @returns {Sharp} * @throws {Error} Invalid parameters */ function toColorspace (colorspace) { return this.toColourspace(colorspace); } /** * Update a colour attribute of the this.options Object. * @private * @param {string} key * @param {string|Object} value * @throws {Error} Invalid value */ function _setBackgroundColourOption (key, value) { if (is.defined(value)) { if (is.object(value) || is.string(value)) { const colour = color(value); this.options[key] = [ colour.red(), colour.green(), colour.blue(), Math.round(colour.alpha() * 255) ]; } else { throw is.invalidParameterError('background', 'object or string', value); } } } /** * Decorate the Sharp prototype with colour-related functions. * @private */ module.exports = function (Sharp) { Object.assign(Sharp.prototype, { // Public tint, greyscale, grayscale, pipelineColourspace, pipelineColorspace, toColourspace, toColorspace, // Private _setBackgroundColourOption }); // Class attributes Sharp.colourspace = colourspace; Sharp.colorspace = colourspace; };