@zxing/browser
Version:
ZXing for JS's browser layer.
151 lines • 7.08 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { IllegalArgumentException, InvertedLuminanceSource, LuminanceSource, } from '@zxing/library';
/**/
var HTMLCanvasElementLuminanceSource = /** @class */ (function (_super) {
__extends(HTMLCanvasElementLuminanceSource, _super);
function HTMLCanvasElementLuminanceSource(canvas) {
var _this = _super.call(this, canvas.width, canvas.height) || this;
_this.canvas = canvas;
_this.tempCanvasElement = null;
_this.buffer = HTMLCanvasElementLuminanceSource.makeBufferFromCanvasImageData(canvas);
return _this;
}
HTMLCanvasElementLuminanceSource.makeBufferFromCanvasImageData = function (canvas) {
var canvasCtx;
try {
canvasCtx = canvas.getContext('2d', { willReadFrequently: true });
}
catch (e) {
canvasCtx = canvas.getContext('2d');
}
if (!canvasCtx) {
throw new Error('Couldn\'t get canvas context.');
}
var imageData = canvasCtx.getImageData(0, 0, canvas.width, canvas.height);
return HTMLCanvasElementLuminanceSource.toGrayscaleBuffer(imageData.data, canvas.width, canvas.height);
};
HTMLCanvasElementLuminanceSource.toGrayscaleBuffer = function (imageBuffer, width, height) {
var grayscaleBuffer = new Uint8ClampedArray(width * height);
for (var i = 0, j = 0, length_1 = imageBuffer.length; i < length_1; i += 4, j++) {
var gray = void 0;
var alpha = imageBuffer[i + 3];
// The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent
// black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a
// barcode image. Force any such pixel to be white:
if (alpha === 0) {
gray = 0xFF;
}
else {
var pixelR = imageBuffer[i];
var pixelG = imageBuffer[i + 1];
var pixelB = imageBuffer[i + 2];
// .299R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC),
// (306*R) >> 10 is approximately equal to R*0.299, and so on.
// 0x200 >> 10 is 0.5, it implements rounding.
// tslint:disable-next-line:no-bitwise
gray = (306 * pixelR + 601 * pixelG + 117 * pixelB + 0x200) >> 10;
}
grayscaleBuffer[j] = gray;
}
return grayscaleBuffer;
};
HTMLCanvasElementLuminanceSource.prototype.getRow = function (y /*int*/, row) {
if (y < 0 || y >= this.getHeight()) {
throw new IllegalArgumentException('Requested row is outside the image: ' + y);
}
var width = this.getWidth();
var start = y * width;
if (row === null) {
row = this.buffer.slice(start, start + width);
}
else {
if (row.length < width) {
row = new Uint8ClampedArray(width);
}
// The underlying raster of image consists of bytes with the luminance values
// TODO: can avoid set/slice?
row.set(this.buffer.slice(start, start + width));
}
return row;
};
HTMLCanvasElementLuminanceSource.prototype.getMatrix = function () {
return this.buffer;
};
HTMLCanvasElementLuminanceSource.prototype.isCropSupported = function () {
return true;
};
HTMLCanvasElementLuminanceSource.prototype.crop = function (left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
_super.prototype.crop.call(this, left, top, width, height);
return this;
};
/**
* This is always true, since the image is a gray-scale image.
*
* @return true
*/
HTMLCanvasElementLuminanceSource.prototype.isRotateSupported = function () {
return true;
};
HTMLCanvasElementLuminanceSource.prototype.rotateCounterClockwise = function () {
this.rotate(-90);
return this;
};
HTMLCanvasElementLuminanceSource.prototype.rotateCounterClockwise45 = function () {
this.rotate(-45);
return this;
};
HTMLCanvasElementLuminanceSource.prototype.invert = function () {
return new InvertedLuminanceSource(this);
};
HTMLCanvasElementLuminanceSource.prototype.getTempCanvasElement = function () {
if (null === this.tempCanvasElement) {
var tempCanvasElement = this.canvas.ownerDocument.createElement('canvas');
tempCanvasElement.width = this.canvas.width;
tempCanvasElement.height = this.canvas.height;
this.tempCanvasElement = tempCanvasElement;
}
return this.tempCanvasElement;
};
HTMLCanvasElementLuminanceSource.prototype.rotate = function (angle) {
var tempCanvasElement = this.getTempCanvasElement();
if (!tempCanvasElement) {
throw new Error('Could not create a Canvas element.');
}
var angleRadians = angle * HTMLCanvasElementLuminanceSource.DEGREE_TO_RADIANS;
// Calculate and set new dimensions for temp canvas
var width = this.canvas.width;
var height = this.canvas.height;
var newWidth = Math.ceil(Math.abs(Math.cos(angleRadians)) * width + Math.abs(Math.sin(angleRadians)) * height);
var newHeight = Math.ceil(Math.abs(Math.sin(angleRadians)) * width + Math.abs(Math.cos(angleRadians)) * height);
tempCanvasElement.width = newWidth;
tempCanvasElement.height = newHeight;
var tempContext = tempCanvasElement.getContext('2d');
if (!tempContext) {
throw new Error('Could not create a Canvas Context element.');
}
// Draw at center of temp canvas to prevent clipping of image data
tempContext.translate(newWidth / 2, newHeight / 2);
tempContext.rotate(angleRadians);
tempContext.drawImage(this.canvas, width / -2, height / -2);
this.buffer = HTMLCanvasElementLuminanceSource.makeBufferFromCanvasImageData(tempCanvasElement);
return this;
};
HTMLCanvasElementLuminanceSource.DEGREE_TO_RADIANS = Math.PI / 180;
return HTMLCanvasElementLuminanceSource;
}(LuminanceSource));
export { HTMLCanvasElementLuminanceSource };
//# sourceMappingURL=HTMLCanvasElementLuminanceSource.js.map