colour.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // Copyright 2013 Lovell Fuller and others.
  2. // SPDX-License-Identifier: Apache-2.0
  3. 'use strict';
  4. const color = require('color');
  5. const is = require('./is');
  6. /**
  7. * Colourspaces.
  8. * @private
  9. */
  10. const colourspace = {
  11. multiband: 'multiband',
  12. 'b-w': 'b-w',
  13. bw: 'b-w',
  14. cmyk: 'cmyk',
  15. srgb: 'srgb'
  16. };
  17. /**
  18. * Tint the image using the provided chroma while preserving the image luminance.
  19. * An alpha channel may be present and will be unchanged by the operation.
  20. *
  21. * @example
  22. * const output = await sharp(input)
  23. * .tint({ r: 255, g: 240, b: 16 })
  24. * .toBuffer();
  25. *
  26. * @param {string|Object} rgb - parsed by the [color](https://www.npmjs.org/package/color) module to extract chroma values.
  27. * @returns {Sharp}
  28. * @throws {Error} Invalid parameter
  29. */
  30. function tint (rgb) {
  31. const colour = color(rgb);
  32. this.options.tintA = colour.a();
  33. this.options.tintB = colour.b();
  34. return this;
  35. }
  36. /**
  37. * Convert to 8-bit greyscale; 256 shades of grey.
  38. * 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.
  39. * By default the output image will be web-friendly sRGB and contain three (identical) color channels.
  40. * This may be overridden by other sharp operations such as `toColourspace('b-w')`,
  41. * which will produce an output image containing one color channel.
  42. * An alpha channel may be present, and will be unchanged by the operation.
  43. *
  44. * @example
  45. * const output = await sharp(input).greyscale().toBuffer();
  46. *
  47. * @param {Boolean} [greyscale=true]
  48. * @returns {Sharp}
  49. */
  50. function greyscale (greyscale) {
  51. this.options.greyscale = is.bool(greyscale) ? greyscale : true;
  52. return this;
  53. }
  54. /**
  55. * Alternative spelling of `greyscale`.
  56. * @param {Boolean} [grayscale=true]
  57. * @returns {Sharp}
  58. */
  59. function grayscale (grayscale) {
  60. return this.greyscale(grayscale);
  61. }
  62. /**
  63. * Set the pipeline colourspace.
  64. *
  65. * The input image will be converted to the provided colourspace at the start of the pipeline.
  66. * All operations will use this colourspace before converting to the output colourspace,
  67. * as defined by {@link #tocolourspace|toColourspace}.
  68. *
  69. * This feature is experimental and has not yet been fully-tested with all operations.
  70. *
  71. * @since 0.29.0
  72. *
  73. * @example
  74. * // Run pipeline in 16 bits per channel RGB while converting final result to 8 bits per channel sRGB.
  75. * await sharp(input)
  76. * .pipelineColourspace('rgb16')
  77. * .toColourspace('srgb')
  78. * .toFile('16bpc-pipeline-to-8bpc-output.png')
  79. *
  80. * @param {string} [colourspace] - pipeline colourspace e.g. `rgb16`, `scrgb`, `lab`, `grey16` [...](https://github.com/libvips/libvips/blob/41cff4e9d0838498487a00623462204eb10ee5b8/libvips/iofuncs/enumtypes.c#L774)
  81. * @returns {Sharp}
  82. * @throws {Error} Invalid parameters
  83. */
  84. function pipelineColourspace (colourspace) {
  85. if (!is.string(colourspace)) {
  86. throw is.invalidParameterError('colourspace', 'string', colourspace);
  87. }
  88. this.options.colourspaceInput = colourspace;
  89. return this;
  90. }
  91. /**
  92. * Alternative spelling of `pipelineColourspace`.
  93. * @param {string} [colorspace] - pipeline colorspace.
  94. * @returns {Sharp}
  95. * @throws {Error} Invalid parameters
  96. */
  97. function pipelineColorspace (colorspace) {
  98. return this.pipelineColourspace(colorspace);
  99. }
  100. /**
  101. * Set the output colourspace.
  102. * By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.
  103. *
  104. * @example
  105. * // Output 16 bits per pixel RGB
  106. * await sharp(input)
  107. * .toColourspace('rgb16')
  108. * .toFile('16-bpp.png')
  109. *
  110. * @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)
  111. * @returns {Sharp}
  112. * @throws {Error} Invalid parameters
  113. */
  114. function toColourspace (colourspace) {
  115. if (!is.string(colourspace)) {
  116. throw is.invalidParameterError('colourspace', 'string', colourspace);
  117. }
  118. this.options.colourspace = colourspace;
  119. return this;
  120. }
  121. /**
  122. * Alternative spelling of `toColourspace`.
  123. * @param {string} [colorspace] - output colorspace.
  124. * @returns {Sharp}
  125. * @throws {Error} Invalid parameters
  126. */
  127. function toColorspace (colorspace) {
  128. return this.toColourspace(colorspace);
  129. }
  130. /**
  131. * Update a colour attribute of the this.options Object.
  132. * @private
  133. * @param {string} key
  134. * @param {string|Object} value
  135. * @throws {Error} Invalid value
  136. */
  137. function _setBackgroundColourOption (key, value) {
  138. if (is.defined(value)) {
  139. if (is.object(value) || is.string(value)) {
  140. const colour = color(value);
  141. this.options[key] = [
  142. colour.red(),
  143. colour.green(),
  144. colour.blue(),
  145. Math.round(colour.alpha() * 255)
  146. ];
  147. } else {
  148. throw is.invalidParameterError('background', 'object or string', value);
  149. }
  150. }
  151. }
  152. /**
  153. * Decorate the Sharp prototype with colour-related functions.
  154. * @private
  155. */
  156. module.exports = function (Sharp) {
  157. Object.assign(Sharp.prototype, {
  158. // Public
  159. tint,
  160. greyscale,
  161. grayscale,
  162. pipelineColourspace,
  163. pipelineColorspace,
  164. toColourspace,
  165. toColorspace,
  166. // Private
  167. _setBackgroundColourOption
  168. });
  169. // Class attributes
  170. Sharp.colourspace = colourspace;
  171. Sharp.colorspace = colourspace;
  172. };