HTMLCanvasElementLuminanceSource.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. var __extends = (this && this.__extends) || (function () {
  2. var extendStatics = function (d, b) {
  3. extendStatics = Object.setPrototypeOf ||
  4. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  5. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  6. return extendStatics(d, b);
  7. };
  8. return function (d, b) {
  9. extendStatics(d, b);
  10. function __() { this.constructor = d; }
  11. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  12. };
  13. })();
  14. import InvertedLuminanceSource from '../core/InvertedLuminanceSource';
  15. import LuminanceSource from '../core/LuminanceSource';
  16. import IllegalArgumentException from '../core/IllegalArgumentException';
  17. /**
  18. * @deprecated Moving to @zxing/browser
  19. */
  20. var HTMLCanvasElementLuminanceSource = /** @class */ (function (_super) {
  21. __extends(HTMLCanvasElementLuminanceSource, _super);
  22. function HTMLCanvasElementLuminanceSource(canvas) {
  23. var _this = _super.call(this, canvas.width, canvas.height) || this;
  24. _this.canvas = canvas;
  25. _this.tempCanvasElement = null;
  26. _this.buffer = HTMLCanvasElementLuminanceSource.makeBufferFromCanvasImageData(canvas);
  27. return _this;
  28. }
  29. HTMLCanvasElementLuminanceSource.makeBufferFromCanvasImageData = function (canvas) {
  30. var imageData = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
  31. return HTMLCanvasElementLuminanceSource.toGrayscaleBuffer(imageData.data, canvas.width, canvas.height);
  32. };
  33. HTMLCanvasElementLuminanceSource.toGrayscaleBuffer = function (imageBuffer, width, height) {
  34. var grayscaleBuffer = new Uint8ClampedArray(width * height);
  35. HTMLCanvasElementLuminanceSource.FRAME_INDEX = !HTMLCanvasElementLuminanceSource.FRAME_INDEX;
  36. if (HTMLCanvasElementLuminanceSource.FRAME_INDEX) {
  37. for (var i = 0, j = 0, length_1 = imageBuffer.length; i < length_1; i += 4, j++) {
  38. var gray = void 0;
  39. var alpha = imageBuffer[i + 3];
  40. // The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent
  41. // black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a
  42. // barcode image. Force any such pixel to be white:
  43. if (alpha === 0) {
  44. gray = 0xFF;
  45. }
  46. else {
  47. var pixelR = imageBuffer[i];
  48. var pixelG = imageBuffer[i + 1];
  49. var pixelB = imageBuffer[i + 2];
  50. // .299R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC),
  51. // (306*R) >> 10 is approximately equal to R*0.299, and so on.
  52. // 0x200 >> 10 is 0.5, it implements rounding.
  53. gray = (306 * pixelR +
  54. 601 * pixelG +
  55. 117 * pixelB +
  56. 0x200) >> 10;
  57. }
  58. grayscaleBuffer[j] = gray;
  59. }
  60. }
  61. else {
  62. for (var i = 0, j = 0, length_2 = imageBuffer.length; i < length_2; i += 4, j++) {
  63. var gray = void 0;
  64. var alpha = imageBuffer[i + 3];
  65. // The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent
  66. // black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a
  67. // barcode image. Force any such pixel to be white:
  68. if (alpha === 0) {
  69. gray = 0xFF;
  70. }
  71. else {
  72. var pixelR = imageBuffer[i];
  73. var pixelG = imageBuffer[i + 1];
  74. var pixelB = imageBuffer[i + 2];
  75. // .299R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC),
  76. // (306*R) >> 10 is approximately equal to R*0.299, and so on.
  77. // 0x200 >> 10 is 0.5, it implements rounding.
  78. gray = (306 * pixelR +
  79. 601 * pixelG +
  80. 117 * pixelB +
  81. 0x200) >> 10;
  82. }
  83. grayscaleBuffer[j] = 0xFF - gray;
  84. }
  85. }
  86. return grayscaleBuffer;
  87. };
  88. HTMLCanvasElementLuminanceSource.prototype.getRow = function (y /*int*/, row) {
  89. if (y < 0 || y >= this.getHeight()) {
  90. throw new IllegalArgumentException('Requested row is outside the image: ' + y);
  91. }
  92. var width = this.getWidth();
  93. var start = y * width;
  94. if (row === null) {
  95. row = this.buffer.slice(start, start + width);
  96. }
  97. else {
  98. if (row.length < width) {
  99. row = new Uint8ClampedArray(width);
  100. }
  101. // The underlying raster of image consists of bytes with the luminance values
  102. // TODO: can avoid set/slice?
  103. row.set(this.buffer.slice(start, start + width));
  104. }
  105. return row;
  106. };
  107. HTMLCanvasElementLuminanceSource.prototype.getMatrix = function () {
  108. return this.buffer;
  109. };
  110. HTMLCanvasElementLuminanceSource.prototype.isCropSupported = function () {
  111. return true;
  112. };
  113. HTMLCanvasElementLuminanceSource.prototype.crop = function (left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
  114. _super.prototype.crop.call(this, left, top, width, height);
  115. return this;
  116. };
  117. /**
  118. * This is always true, since the image is a gray-scale image.
  119. *
  120. * @return true
  121. */
  122. HTMLCanvasElementLuminanceSource.prototype.isRotateSupported = function () {
  123. return true;
  124. };
  125. HTMLCanvasElementLuminanceSource.prototype.rotateCounterClockwise = function () {
  126. this.rotate(-90);
  127. return this;
  128. };
  129. HTMLCanvasElementLuminanceSource.prototype.rotateCounterClockwise45 = function () {
  130. this.rotate(-45);
  131. return this;
  132. };
  133. HTMLCanvasElementLuminanceSource.prototype.getTempCanvasElement = function () {
  134. if (null === this.tempCanvasElement) {
  135. var tempCanvasElement = this.canvas.ownerDocument.createElement('canvas');
  136. tempCanvasElement.width = this.canvas.width;
  137. tempCanvasElement.height = this.canvas.height;
  138. this.tempCanvasElement = tempCanvasElement;
  139. }
  140. return this.tempCanvasElement;
  141. };
  142. HTMLCanvasElementLuminanceSource.prototype.rotate = function (angle) {
  143. var tempCanvasElement = this.getTempCanvasElement();
  144. var tempContext = tempCanvasElement.getContext('2d');
  145. var angleRadians = angle * HTMLCanvasElementLuminanceSource.DEGREE_TO_RADIANS;
  146. // Calculate and set new dimensions for temp canvas
  147. var width = this.canvas.width;
  148. var height = this.canvas.height;
  149. var newWidth = Math.ceil(Math.abs(Math.cos(angleRadians)) * width + Math.abs(Math.sin(angleRadians)) * height);
  150. var newHeight = Math.ceil(Math.abs(Math.sin(angleRadians)) * width + Math.abs(Math.cos(angleRadians)) * height);
  151. tempCanvasElement.width = newWidth;
  152. tempCanvasElement.height = newHeight;
  153. // Draw at center of temp canvas to prevent clipping of image data
  154. tempContext.translate(newWidth / 2, newHeight / 2);
  155. tempContext.rotate(angleRadians);
  156. tempContext.drawImage(this.canvas, width / -2, height / -2);
  157. this.buffer = HTMLCanvasElementLuminanceSource.makeBufferFromCanvasImageData(tempCanvasElement);
  158. return this;
  159. };
  160. HTMLCanvasElementLuminanceSource.prototype.invert = function () {
  161. return new InvertedLuminanceSource(this);
  162. };
  163. HTMLCanvasElementLuminanceSource.DEGREE_TO_RADIANS = Math.PI / 180;
  164. HTMLCanvasElementLuminanceSource.FRAME_INDEX = true;
  165. return HTMLCanvasElementLuminanceSource;
  166. }(LuminanceSource));
  167. export { HTMLCanvasElementLuminanceSource };