channel.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. 'use strict';
  2. const is = require('./is');
  3. /**
  4. * Boolean operations for bandbool.
  5. * @private
  6. */
  7. const bool = {
  8. and: 'and',
  9. or: 'or',
  10. eor: 'eor'
  11. };
  12. /**
  13. * Remove alpha channel, if any. This is a no-op if the image does not have an alpha channel.
  14. *
  15. * @example
  16. * sharp('rgba.png')
  17. * .removeAlpha()
  18. * .toFile('rgb.png', function(err, info) {
  19. * // rgb.png is a 3 channel image without an alpha channel
  20. * });
  21. *
  22. * @returns {Sharp}
  23. */
  24. function removeAlpha () {
  25. this.options.removeAlpha = true;
  26. return this;
  27. }
  28. /**
  29. * Ensure alpha channel, if missing. The added alpha channel will be fully opaque. This is a no-op if the image already has an alpha channel.
  30. *
  31. * @since 0.21.2
  32. *
  33. * @example
  34. * sharp('rgb.jpg')
  35. * .ensureAlpha()
  36. * .toFile('rgba.png', function(err, info) {
  37. * // rgba.png is a 4 channel image with a fully opaque alpha channel
  38. * });
  39. *
  40. * @returns {Sharp}
  41. */
  42. function ensureAlpha () {
  43. this.options.ensureAlpha = true;
  44. return this;
  45. }
  46. /**
  47. * Extract a single channel from a multi-channel image.
  48. *
  49. * @example
  50. * sharp(input)
  51. * .extractChannel('green')
  52. * .toColourspace('b-w')
  53. * .toFile('green.jpg', function(err, info) {
  54. * // info.channels === 1
  55. * // green.jpg is a greyscale image containing the green channel of the input
  56. * });
  57. *
  58. * @param {number|string} channel - zero-indexed band number to extract, or `red`, `green` or `blue` as alternative to `0`, `1` or `2` respectively.
  59. * @returns {Sharp}
  60. * @throws {Error} Invalid channel
  61. */
  62. function extractChannel (channel) {
  63. if (channel === 'red') {
  64. channel = 0;
  65. } else if (channel === 'green') {
  66. channel = 1;
  67. } else if (channel === 'blue') {
  68. channel = 2;
  69. }
  70. if (is.integer(channel) && is.inRange(channel, 0, 4)) {
  71. this.options.extractChannel = channel;
  72. } else {
  73. throw is.invalidParameterError('channel', 'integer or one of: red, green, blue', channel);
  74. }
  75. return this;
  76. }
  77. /**
  78. * Join one or more channels to the image.
  79. * The meaning of the added channels depends on the output colourspace, set with `toColourspace()`.
  80. * By default the output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.
  81. * Channel ordering follows vips convention:
  82. * - sRGB: 0: Red, 1: Green, 2: Blue, 3: Alpha.
  83. * - CMYK: 0: Magenta, 1: Cyan, 2: Yellow, 3: Black, 4: Alpha.
  84. *
  85. * Buffers may be any of the image formats supported by sharp: JPEG, PNG, WebP, GIF, SVG, TIFF or raw pixel image data.
  86. * For raw pixel input, the `options` object should contain a `raw` attribute, which follows the format of the attribute of the same name in the `sharp()` constructor.
  87. *
  88. * @param {Array<string|Buffer>|string|Buffer} images - one or more images (file paths, Buffers).
  89. * @param {Object} options - image options, see `sharp()` constructor.
  90. * @returns {Sharp}
  91. * @throws {Error} Invalid parameters
  92. */
  93. function joinChannel (images, options) {
  94. if (Array.isArray(images)) {
  95. images.forEach(function (image) {
  96. this.options.joinChannelIn.push(this._createInputDescriptor(image, options));
  97. }, this);
  98. } else {
  99. this.options.joinChannelIn.push(this._createInputDescriptor(images, options));
  100. }
  101. return this;
  102. }
  103. /**
  104. * Perform a bitwise boolean operation on all input image channels (bands) to produce a single channel output image.
  105. *
  106. * @example
  107. * sharp('3-channel-rgb-input.png')
  108. * .bandbool(sharp.bool.and)
  109. * .toFile('1-channel-output.png', function (err, info) {
  110. * // The output will be a single channel image where each pixel `P = R & G & B`.
  111. * // If `I(1,1) = [247, 170, 14] = [0b11110111, 0b10101010, 0b00001111]`
  112. * // then `O(1,1) = 0b11110111 & 0b10101010 & 0b00001111 = 0b00000010 = 2`.
  113. * });
  114. *
  115. * @param {string} boolOp - one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively.
  116. * @returns {Sharp}
  117. * @throws {Error} Invalid parameters
  118. */
  119. function bandbool (boolOp) {
  120. if (is.string(boolOp) && is.inArray(boolOp, ['and', 'or', 'eor'])) {
  121. this.options.bandBoolOp = boolOp;
  122. } else {
  123. throw is.invalidParameterError('boolOp', 'one of: and, or, eor', boolOp);
  124. }
  125. return this;
  126. }
  127. /**
  128. * Decorate the Sharp prototype with channel-related functions.
  129. * @private
  130. */
  131. module.exports = function (Sharp) {
  132. Object.assign(Sharp.prototype, {
  133. // Public instance functions
  134. removeAlpha,
  135. ensureAlpha,
  136. extractChannel,
  137. joinChannel,
  138. bandbool
  139. });
  140. // Class attributes
  141. Sharp.bool = bool;
  142. };