colour.js 5.2 KB

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