Add barcode-detector-api-polyfill dependency and update environment variable declarations in SvelteKit project
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m50s

This commit is contained in:
eewing
2026-02-17 14:58:53 -06:00
parent cff20a652a
commit 9022114c8d
2137 changed files with 201996 additions and 762 deletions
+12
View File
@@ -0,0 +1,12 @@
export * from './browser/BrowserAztecCodeReader';
export * from './browser/BrowserBarcodeReader';
export * from './browser/BrowserCodeReader';
export * from './browser/BrowserDatamatrixCodeReader';
export * from './browser/BrowserMultiFormatReader';
export * from './browser/BrowserPDF417Reader';
export * from './browser/BrowserQRCodeReader';
export * from './browser/BrowserQRCodeSvgWriter';
export * from './browser/DecodeContinuouslyCallback';
export * from './browser/HTMLCanvasElementLuminanceSource';
export * from './browser/HTMLVisualMediaElement';
export * from './browser/VideoInputDevice';
+13
View File
@@ -0,0 +1,13 @@
// browser
export * from './browser/BrowserAztecCodeReader';
export * from './browser/BrowserBarcodeReader';
export * from './browser/BrowserCodeReader';
export * from './browser/BrowserDatamatrixCodeReader';
export * from './browser/BrowserMultiFormatReader';
export * from './browser/BrowserPDF417Reader';
export * from './browser/BrowserQRCodeReader';
export * from './browser/BrowserQRCodeSvgWriter';
export * from './browser/DecodeContinuouslyCallback';
export * from './browser/HTMLCanvasElementLuminanceSource';
export * from './browser/HTMLVisualMediaElement';
export * from './browser/VideoInputDevice';
+16
View File
@@ -0,0 +1,16 @@
import { BrowserCodeReader } from './BrowserCodeReader';
/**
* Aztec Code reader to use from browser.
*
* @class BrowserAztecCodeReader
* @extends {BrowserCodeReader}
*/
export declare class BrowserAztecCodeReader extends BrowserCodeReader {
/**
* Creates an instance of BrowserAztecCodeReader.
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
*
* @memberOf BrowserAztecCodeReader
*/
constructor(timeBetweenScansMillis?: number);
}
+19
View File
@@ -0,0 +1,19 @@
import { BrowserCodeReader } from './BrowserCodeReader';
import AztecReader from '../core/aztec/AztecReader';
/**
* Aztec Code reader to use from browser.
*
* @class BrowserAztecCodeReader
* @extends {BrowserCodeReader}
*/
export class BrowserAztecCodeReader extends BrowserCodeReader {
/**
* Creates an instance of BrowserAztecCodeReader.
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
*
* @memberOf BrowserAztecCodeReader
*/
constructor(timeBetweenScansMillis = 500) {
super(new AztecReader(), timeBetweenScansMillis);
}
}
+15
View File
@@ -0,0 +1,15 @@
import { BrowserCodeReader } from './BrowserCodeReader';
import DecodeHintType from '../core/DecodeHintType';
/**
* @deprecated Moving to @zxing/browser
*
* Barcode reader reader to use from browser.
*/
export declare class BrowserBarcodeReader extends BrowserCodeReader {
/**
* Creates an instance of BrowserBarcodeReader.
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
* @param {Map<DecodeHintType, any>} hints
*/
constructor(timeBetweenScansMillis?: number, hints?: Map<DecodeHintType, any>);
}
+17
View File
@@ -0,0 +1,17 @@
import { BrowserCodeReader } from './BrowserCodeReader';
import MultiFormatOneDReader from '../core/oned/MultiFormatOneDReader';
/**
* @deprecated Moving to @zxing/browser
*
* Barcode reader reader to use from browser.
*/
export class BrowserBarcodeReader extends BrowserCodeReader {
/**
* Creates an instance of BrowserBarcodeReader.
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
* @param {Map<DecodeHintType, any>} hints
*/
constructor(timeBetweenScansMillis = 500, hints) {
super(new MultiFormatOneDReader(hints), timeBetweenScansMillis, hints);
}
}
+411
View File
@@ -0,0 +1,411 @@
import BinaryBitmap from '../core/BinaryBitmap';
import DecodeHintType from '../core/DecodeHintType';
import Reader from '../core/Reader';
import Result from '../core/Result';
import { DecodeContinuouslyCallback } from './DecodeContinuouslyCallback';
import { HTMLVisualMediaElement } from './HTMLVisualMediaElement';
import { VideoInputDevice } from './VideoInputDevice';
/**
* @deprecated Moving to @zxing/browser
*
* Base class for browser code reader.
*/
export declare class BrowserCodeReader {
protected readonly reader: Reader;
protected timeBetweenScansMillis: number;
protected _hints?: Map<DecodeHintType, any>;
/**
* If navigator is present.
*/
get hasNavigator(): boolean;
/**
* If mediaDevices under navigator is supported.
*/
get isMediaDevicesSuported(): boolean;
/**
* If enumerateDevices under navigator is supported.
*/
get canEnumerateDevices(): boolean;
/**
* This will break the loop.
*/
private _stopContinuousDecode;
/**
* This will break the loop.
*/
private _stopAsyncDecode;
/**
* Delay time between decode attempts made by the scanner.
*/
protected _timeBetweenDecodingAttempts: number;
/** Time between two decoding tries in milli seconds. */
get timeBetweenDecodingAttempts(): number;
/**
* Change the time span the decoder waits between two decoding tries.
*
* @param {number} millis Time between two decoding tries in milli seconds.
*/
set timeBetweenDecodingAttempts(millis: number);
/**
* The HTML canvas element, used to draw the video or image's frame for decoding.
*/
protected captureCanvas: HTMLCanvasElement;
/**
* The HTML canvas element context.
*/
protected captureCanvasContext: CanvasRenderingContext2D;
/**
* The HTML image element, used as a fallback for the video element when decoding.
*/
protected imageElement: HTMLImageElement;
/**
* Should contain the current registered listener for image loading,
* used to unregister that listener when needed.
*/
protected imageLoadedListener: EventListener;
/**
* The stream output from camera.
*/
protected stream: MediaStream;
/**
* The HTML video element, used to display the camera stream.
*/
protected videoElement: HTMLVideoElement;
/**
* Should contain the current registered listener for video loaded-metadata,
* used to unregister that listener when needed.
*/
protected videoCanPlayListener: EventListener;
/**
* Should contain the current registered listener for video play-ended,
* used to unregister that listener when needed.
*/
protected videoEndedListener: EventListener;
/**
* Should contain the current registered listener for video playing,
* used to unregister that listener when needed.
*/
protected videoPlayingEventListener: EventListener;
/**
* Sets the hints.
*/
set hints(hints: Map<DecodeHintType, any>);
/**
* Sets the hints.
*/
get hints(): Map<DecodeHintType, any>;
/**
* Creates an instance of BrowserCodeReader.
* @param {Reader} reader The reader instance to decode the barcode
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent successful decode tries
*
* @memberOf BrowserCodeReader
*/
constructor(reader: Reader, timeBetweenScansMillis?: number, _hints?: Map<DecodeHintType, any>);
/**
* Lists all the available video input devices.
*/
listVideoInputDevices(): Promise<MediaDeviceInfo[]>;
/**
* Obtain the list of available devices with type 'videoinput'.
*
* @returns {Promise<VideoInputDevice[]>} an array of available video input devices
*
* @memberOf BrowserCodeReader
*
* @deprecated Use `listVideoInputDevices` instead.
*/
getVideoInputDevices(): Promise<VideoInputDevice[]>;
/**
* Let's you find a device using it's Id.
*/
findDeviceById(deviceId: string): Promise<MediaDeviceInfo>;
/**
* Decodes the barcode from the device specified by deviceId while showing the video in the specified video element.
*
* @param deviceId the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
* @param video the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns The decoding result.
*
* @memberOf BrowserCodeReader
*
* @deprecated Use `decodeOnceFromVideoDevice` instead.
*/
decodeFromInputVideoDevice(deviceId?: string, videoSource?: string | HTMLVideoElement): Promise<Result>;
/**
* In one attempt, tries to decode the barcode from the device specified by deviceId while showing the video in the specified video element.
*
* @param deviceId the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
* @param video the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeOnceFromVideoDevice(deviceId?: string, videoSource?: string | HTMLVideoElement): Promise<Result>;
/**
* In one attempt, tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
*
* @param constraints the media stream constraints to get s valid media stream to decode from
* @param video the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeOnceFromConstraints(constraints: MediaStreamConstraints, videoSource?: string | HTMLVideoElement): Promise<Result>;
/**
* In one attempt, tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
*
* @param {MediaStream} [constraints] the media stream constraints to get s valid media stream to decode from
* @param {string|HTMLVideoElement} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeOnceFromStream(stream: MediaStream, videoSource?: string | HTMLVideoElement): Promise<Result>;
/**
* Continuously decodes the barcode from the device specified by device while showing the video in the specified video element.
*
* @param {string|null} [deviceId] the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
* @param {string|HTMLVideoElement|null} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns {Promise<void>}
*
* @memberOf BrowserCodeReader
*
* @deprecated Use `decodeFromVideoDevice` instead.
*/
decodeFromInputVideoDeviceContinuously(deviceId: string | null, videoSource: string | HTMLVideoElement | null, callbackFn: DecodeContinuouslyCallback): Promise<void>;
/**
* Continuously tries to decode the barcode from the device specified by device while showing the video in the specified video element.
*
* @param {string|null} [deviceId] the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
* @param {string|HTMLVideoElement|null} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns {Promise<void>}
*
* @memberOf BrowserCodeReader
*/
decodeFromVideoDevice(deviceId: string | null, videoSource: string | HTMLVideoElement | null, callbackFn: DecodeContinuouslyCallback): Promise<void>;
/**
* Continuously tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
*
* @param {MediaStream} [constraints] the media stream constraints to get s valid media stream to decode from
* @param {string|HTMLVideoElement} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeFromConstraints(constraints: MediaStreamConstraints, videoSource: string | HTMLVideoElement, callbackFn: DecodeContinuouslyCallback): Promise<void>;
/**
* In one attempt, tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
*
* @param {MediaStream} [constraints] the media stream constraints to get s valid media stream to decode from
* @param {string|HTMLVideoElement} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeFromStream(stream: MediaStream, videoSource: string | HTMLVideoElement, callbackFn: DecodeContinuouslyCallback): Promise<void>;
/**
* Breaks the decoding loop.
*/
stopAsyncDecode(): void;
/**
* Breaks the decoding loop.
*/
stopContinuousDecode(): void;
/**
* Sets the new stream and request a new decoding-with-delay.
*
* @param stream The stream to be shown in the video element.
* @param decodeFn A callback for the decode method.
*/
protected attachStreamToVideo(stream: MediaStream, videoSource: string | HTMLVideoElement): Promise<HTMLVideoElement>;
/**
*
* @param videoElement
*/
protected playVideoOnLoadAsync(videoElement: HTMLVideoElement): Promise<void>;
/**
* Binds listeners and callbacks to the videoElement.
*
* @param element
* @param callbackFn
*/
protected playVideoOnLoad(element: HTMLVideoElement, callbackFn: EventListener): void;
/**
* Checks if the given video element is currently playing.
*/
isVideoPlaying(video: HTMLVideoElement): boolean;
/**
* Just tries to play the video and logs any errors.
* The play call is only made is the video is not already playing.
*/
tryPlayVideo(videoElement: HTMLVideoElement): Promise<void>;
/**
* Searches and validates a media element.
*/
getMediaElement(mediaElementId: string, type: string): HTMLVisualMediaElement;
/**
* Decodes the barcode from an image.
*
* @param {(string|HTMLImageElement)} [source] The image element that can be either an element id or the element itself. Can be undefined in which case the decoding will be done from the imageUrl parameter.
* @param {string} [url]
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeFromImage(source?: string | HTMLImageElement, url?: string): Promise<Result>;
/**
* Decodes the barcode from a video.
*
* @param {(string|HTMLImageElement)} [source] The image element that can be either an element id or the element itself. Can be undefined in which case the decoding will be done from the imageUrl parameter.
* @param {string} [url]
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeFromVideo(source?: string | HTMLVideoElement, url?: string): Promise<Result>;
/**
* Decodes continuously the barcode from a video.
*
* @param {(string|HTMLImageElement)} [source] The image element that can be either an element id or the element itself. Can be undefined in which case the decoding will be done from the imageUrl parameter.
* @param {string} [url]
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*
* @experimental
*/
decodeFromVideoContinuously(source: string | HTMLVideoElement | null, url: string | null, callbackFn: DecodeContinuouslyCallback): Promise<void>;
/**
* Decodes something from an image HTML element.
*/
decodeFromImageElement(source: string | HTMLImageElement): Promise<Result>;
/**
* Decodes something from an image HTML element.
*/
decodeFromVideoElement(source: string | HTMLVideoElement): Promise<Result>;
/**
* Decodes something from an image HTML element.
*/
decodeFromVideoElementContinuously(source: string | HTMLVideoElement, callbackFn: DecodeContinuouslyCallback): Promise<void>;
/**
* Sets up the video source so it can be decoded when loaded.
*
* @param source The video source element.
*/
private _decodeFromVideoElementSetup;
/**
* Decodes an image from a URL.
*/
decodeFromImageUrl(url?: string): Promise<Result>;
/**
* Decodes an image from a URL.
*/
decodeFromVideoUrl(url: string): Promise<Result>;
/**
* Decodes an image from a URL.
*
* @experimental
*/
decodeFromVideoUrlContinuously(url: string, callbackFn: DecodeContinuouslyCallback): Promise<void>;
private _decodeOnLoadImage;
private _decodeOnLoadVideo;
private _decodeOnLoadVideoContinuously;
isImageLoaded(img: HTMLImageElement): boolean;
prepareImageElement(imageSource?: HTMLImageElement | string): HTMLImageElement;
/**
* Sets a HTMLVideoElement for scanning or creates a new one.
*
* @param videoSource The HTMLVideoElement to be set.
*/
prepareVideoElement(videoSource?: HTMLVideoElement | string): HTMLVideoElement;
/**
* Tries to decode from the video input until it finds some value.
*/
decodeOnce(element: HTMLVisualMediaElement, retryIfNotFound?: boolean, retryIfChecksumOrFormatError?: boolean): Promise<Result>;
/**
* Continuously decodes from video input.
*/
decodeContinuously(element: HTMLVideoElement, callbackFn: DecodeContinuouslyCallback): void;
/**
* Gets the BinaryBitmap for ya! (and decodes it)
*/
decode(element: HTMLVisualMediaElement): Result;
/**
* Creates a binaryBitmap based in some image source.
*
* @param mediaElement HTML element containing drawable image source.
*/
createBinaryBitmap(mediaElement: HTMLVisualMediaElement): BinaryBitmap;
/**
*
*/
protected getCaptureCanvasContext(mediaElement?: HTMLVisualMediaElement): CanvasRenderingContext2D;
/**
*
*/
protected getCaptureCanvas(mediaElement?: HTMLVisualMediaElement): HTMLCanvasElement;
/**
* Overwriting this allows you to manipulate the next frame in anyway you want before decode.
*/
drawFrameOnCanvas(srcElement: HTMLVideoElement, dimensions?: {
sx: number;
sy: number;
sWidth: number;
sHeight: number;
dx: number;
dy: number;
dWidth: number;
dHeight: number;
}, canvasElementContext?: CanvasRenderingContext2D): void;
/**
* Ovewriting this allows you to manipulate the snapshot image in anyway you want before decode.
*/
drawImageOnCanvas(srcElement: HTMLImageElement, dimensions?: {
sx: number;
sy: number;
sWidth: number;
sHeight: number;
dx: number;
dy: number;
dWidth: number;
dHeight: number;
}, canvasElementContext?: CanvasRenderingContext2D): void;
/**
* Call the encapsulated readers decode
*/
decodeBitmap(binaryBitmap: BinaryBitmap): Result;
/**
* 🖌 Prepares the canvas for capture and scan frames.
*/
createCaptureCanvas(mediaElement?: HTMLVisualMediaElement): HTMLCanvasElement;
/**
* Stops the continuous scan and cleans the stream.
*/
protected stopStreams(): void;
/**
* Resets the code reader to the initial state. Cancels any ongoing barcode scanning from video or camera.
*
* @memberOf BrowserCodeReader
*/
reset(): void;
private _destroyVideoElement;
private _destroyImageElement;
/**
* Cleans canvas references 🖌
*/
private _destroyCaptureCanvas;
/**
* Defines what the videoElement src will be.
*
* @param videoElement
* @param stream
*/
addVideoSource(videoElement: HTMLVideoElement, stream: MediaStream): void;
/**
* Unbinds a HTML video src property.
*
* @param videoElement
*/
private cleanVideoSource;
}
+872
View File
@@ -0,0 +1,872 @@
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import ArgumentException from '../core/ArgumentException';
import BinaryBitmap from '../core/BinaryBitmap';
import ChecksumException from '../core/ChecksumException';
import HybridBinarizer from '../core/common/HybridBinarizer';
import FormatException from '../core/FormatException';
import NotFoundException from '../core/NotFoundException';
import { HTMLCanvasElementLuminanceSource } from './HTMLCanvasElementLuminanceSource';
import { VideoInputDevice } from './VideoInputDevice';
/**
* @deprecated Moving to @zxing/browser
*
* Base class for browser code reader.
*/
export class BrowserCodeReader {
/**
* Creates an instance of BrowserCodeReader.
* @param {Reader} reader The reader instance to decode the barcode
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent successful decode tries
*
* @memberOf BrowserCodeReader
*/
constructor(reader, timeBetweenScansMillis = 500, _hints) {
this.reader = reader;
this.timeBetweenScansMillis = timeBetweenScansMillis;
this._hints = _hints;
/**
* This will break the loop.
*/
this._stopContinuousDecode = false;
/**
* This will break the loop.
*/
this._stopAsyncDecode = false;
/**
* Delay time between decode attempts made by the scanner.
*/
this._timeBetweenDecodingAttempts = 0;
}
/**
* If navigator is present.
*/
get hasNavigator() {
return typeof navigator !== 'undefined';
}
/**
* If mediaDevices under navigator is supported.
*/
get isMediaDevicesSuported() {
return this.hasNavigator && !!navigator.mediaDevices;
}
/**
* If enumerateDevices under navigator is supported.
*/
get canEnumerateDevices() {
return !!(this.isMediaDevicesSuported && navigator.mediaDevices.enumerateDevices);
}
/** Time between two decoding tries in milli seconds. */
get timeBetweenDecodingAttempts() {
return this._timeBetweenDecodingAttempts;
}
/**
* Change the time span the decoder waits between two decoding tries.
*
* @param {number} millis Time between two decoding tries in milli seconds.
*/
set timeBetweenDecodingAttempts(millis) {
this._timeBetweenDecodingAttempts = millis < 0 ? 0 : millis;
}
/**
* Sets the hints.
*/
set hints(hints) {
this._hints = hints || null;
}
/**
* Sets the hints.
*/
get hints() {
return this._hints;
}
/**
* Lists all the available video input devices.
*/
listVideoInputDevices() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.hasNavigator) {
throw new Error("Can't enumerate devices, navigator is not present.");
}
if (!this.canEnumerateDevices) {
throw new Error("Can't enumerate devices, method not supported.");
}
const devices = yield navigator.mediaDevices.enumerateDevices();
const videoDevices = [];
for (const device of devices) {
const kind = device.kind === 'video' ? 'videoinput' : device.kind;
if (kind !== 'videoinput') {
continue;
}
const deviceId = device.deviceId || device.id;
const label = device.label || `Video device ${videoDevices.length + 1}`;
const groupId = device.groupId;
const videoDevice = { deviceId, label, kind, groupId };
videoDevices.push(videoDevice);
}
return videoDevices;
});
}
/**
* Obtain the list of available devices with type 'videoinput'.
*
* @returns {Promise<VideoInputDevice[]>} an array of available video input devices
*
* @memberOf BrowserCodeReader
*
* @deprecated Use `listVideoInputDevices` instead.
*/
getVideoInputDevices() {
return __awaiter(this, void 0, void 0, function* () {
const devices = yield this.listVideoInputDevices();
return devices.map(d => new VideoInputDevice(d.deviceId, d.label));
});
}
/**
* Let's you find a device using it's Id.
*/
findDeviceById(deviceId) {
return __awaiter(this, void 0, void 0, function* () {
const devices = yield this.listVideoInputDevices();
if (!devices) {
return null;
}
return devices.find(x => x.deviceId === deviceId);
});
}
/**
* Decodes the barcode from the device specified by deviceId while showing the video in the specified video element.
*
* @param deviceId the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
* @param video the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns The decoding result.
*
* @memberOf BrowserCodeReader
*
* @deprecated Use `decodeOnceFromVideoDevice` instead.
*/
decodeFromInputVideoDevice(deviceId, videoSource) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.decodeOnceFromVideoDevice(deviceId, videoSource);
});
}
/**
* In one attempt, tries to decode the barcode from the device specified by deviceId while showing the video in the specified video element.
*
* @param deviceId the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
* @param video the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeOnceFromVideoDevice(deviceId, videoSource) {
return __awaiter(this, void 0, void 0, function* () {
this.reset();
let videoConstraints;
if (!deviceId) {
videoConstraints = { facingMode: 'environment' };
}
else {
videoConstraints = { deviceId: { exact: deviceId } };
}
const constraints = { video: videoConstraints };
return yield this.decodeOnceFromConstraints(constraints, videoSource);
});
}
/**
* In one attempt, tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
*
* @param constraints the media stream constraints to get s valid media stream to decode from
* @param video the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeOnceFromConstraints(constraints, videoSource) {
return __awaiter(this, void 0, void 0, function* () {
const stream = yield navigator.mediaDevices.getUserMedia(constraints);
return yield this.decodeOnceFromStream(stream, videoSource);
});
}
/**
* In one attempt, tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
*
* @param {MediaStream} [constraints] the media stream constraints to get s valid media stream to decode from
* @param {string|HTMLVideoElement} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeOnceFromStream(stream, videoSource) {
return __awaiter(this, void 0, void 0, function* () {
this.reset();
const video = yield this.attachStreamToVideo(stream, videoSource);
const result = yield this.decodeOnce(video);
return result;
});
}
/**
* Continuously decodes the barcode from the device specified by device while showing the video in the specified video element.
*
* @param {string|null} [deviceId] the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
* @param {string|HTMLVideoElement|null} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns {Promise<void>}
*
* @memberOf BrowserCodeReader
*
* @deprecated Use `decodeFromVideoDevice` instead.
*/
decodeFromInputVideoDeviceContinuously(deviceId, videoSource, callbackFn) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.decodeFromVideoDevice(deviceId, videoSource, callbackFn);
});
}
/**
* Continuously tries to decode the barcode from the device specified by device while showing the video in the specified video element.
*
* @param {string|null} [deviceId] the id of one of the devices obtained after calling getVideoInputDevices. Can be undefined, in this case it will decode from one of the available devices, preffering the main camera (environment facing) if available.
* @param {string|HTMLVideoElement|null} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns {Promise<void>}
*
* @memberOf BrowserCodeReader
*/
decodeFromVideoDevice(deviceId, videoSource, callbackFn) {
return __awaiter(this, void 0, void 0, function* () {
let videoConstraints;
if (!deviceId) {
videoConstraints = { facingMode: 'environment' };
}
else {
videoConstraints = { deviceId: { exact: deviceId } };
}
const constraints = { video: videoConstraints };
return yield this.decodeFromConstraints(constraints, videoSource, callbackFn);
});
}
/**
* Continuously tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
*
* @param {MediaStream} [constraints] the media stream constraints to get s valid media stream to decode from
* @param {string|HTMLVideoElement} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeFromConstraints(constraints, videoSource, callbackFn) {
return __awaiter(this, void 0, void 0, function* () {
const stream = yield navigator.mediaDevices.getUserMedia(constraints);
return yield this.decodeFromStream(stream, videoSource, callbackFn);
});
}
/**
* In one attempt, tries to decode the barcode from a stream obtained from the given constraints while showing the video in the specified video element.
*
* @param {MediaStream} [constraints] the media stream constraints to get s valid media stream to decode from
* @param {string|HTMLVideoElement} [video] the video element in page where to show the video while decoding. Can be either an element id or directly an HTMLVideoElement. Can be undefined, in which case no video will be shown.
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeFromStream(stream, videoSource, callbackFn) {
return __awaiter(this, void 0, void 0, function* () {
this.reset();
const video = yield this.attachStreamToVideo(stream, videoSource);
return yield this.decodeContinuously(video, callbackFn);
});
}
/**
* Breaks the decoding loop.
*/
stopAsyncDecode() {
this._stopAsyncDecode = true;
}
/**
* Breaks the decoding loop.
*/
stopContinuousDecode() {
this._stopContinuousDecode = true;
}
/**
* Sets the new stream and request a new decoding-with-delay.
*
* @param stream The stream to be shown in the video element.
* @param decodeFn A callback for the decode method.
*/
attachStreamToVideo(stream, videoSource) {
return __awaiter(this, void 0, void 0, function* () {
const videoElement = this.prepareVideoElement(videoSource);
this.addVideoSource(videoElement, stream);
this.videoElement = videoElement;
this.stream = stream;
yield this.playVideoOnLoadAsync(videoElement);
return videoElement;
});
}
/**
*
* @param videoElement
*/
playVideoOnLoadAsync(videoElement) {
return new Promise((resolve, reject) => this.playVideoOnLoad(videoElement, () => resolve()));
}
/**
* Binds listeners and callbacks to the videoElement.
*
* @param element
* @param callbackFn
*/
playVideoOnLoad(element, callbackFn) {
this.videoEndedListener = () => this.stopStreams();
this.videoCanPlayListener = () => this.tryPlayVideo(element);
element.addEventListener('ended', this.videoEndedListener);
element.addEventListener('canplay', this.videoCanPlayListener);
element.addEventListener('playing', callbackFn);
// if canplay was already fired, we won't know when to play, so just give it a try
this.tryPlayVideo(element);
}
/**
* Checks if the given video element is currently playing.
*/
isVideoPlaying(video) {
return (video.currentTime > 0 &&
!video.paused &&
!video.ended &&
video.readyState > 2);
}
/**
* Just tries to play the video and logs any errors.
* The play call is only made is the video is not already playing.
*/
tryPlayVideo(videoElement) {
return __awaiter(this, void 0, void 0, function* () {
if (this.isVideoPlaying(videoElement)) {
console.warn('Trying to play video that is already playing.');
return;
}
try {
yield videoElement.play();
}
catch (_a) {
console.warn('It was not possible to play the video.');
}
});
}
/**
* Searches and validates a media element.
*/
getMediaElement(mediaElementId, type) {
const mediaElement = document.getElementById(mediaElementId);
if (!mediaElement) {
throw new ArgumentException(`element with id '${mediaElementId}' not found`);
}
if (mediaElement.nodeName.toLowerCase() !== type.toLowerCase()) {
throw new ArgumentException(`element with id '${mediaElementId}' must be an ${type} element`);
}
return mediaElement;
}
/**
* Decodes the barcode from an image.
*
* @param {(string|HTMLImageElement)} [source] The image element that can be either an element id or the element itself. Can be undefined in which case the decoding will be done from the imageUrl parameter.
* @param {string} [url]
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeFromImage(source, url) {
if (!source && !url) {
throw new ArgumentException('either imageElement with a src set or an url must be provided');
}
if (url && !source) {
return this.decodeFromImageUrl(url);
}
return this.decodeFromImageElement(source);
}
/**
* Decodes the barcode from a video.
*
* @param {(string|HTMLImageElement)} [source] The image element that can be either an element id or the element itself. Can be undefined in which case the decoding will be done from the imageUrl parameter.
* @param {string} [url]
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*/
decodeFromVideo(source, url) {
if (!source && !url) {
throw new ArgumentException('Either an element with a src set or an URL must be provided');
}
if (url && !source) {
return this.decodeFromVideoUrl(url);
}
return this.decodeFromVideoElement(source);
}
/**
* Decodes continuously the barcode from a video.
*
* @param {(string|HTMLImageElement)} [source] The image element that can be either an element id or the element itself. Can be undefined in which case the decoding will be done from the imageUrl parameter.
* @param {string} [url]
* @returns {Promise<Result>} The decoding result.
*
* @memberOf BrowserCodeReader
*
* @experimental
*/
decodeFromVideoContinuously(source, url, callbackFn) {
if (undefined === source && undefined === url) {
throw new ArgumentException('Either an element with a src set or an URL must be provided');
}
if (url && !source) {
return this.decodeFromVideoUrlContinuously(url, callbackFn);
}
return this.decodeFromVideoElementContinuously(source, callbackFn);
}
/**
* Decodes something from an image HTML element.
*/
decodeFromImageElement(source) {
if (!source) {
throw new ArgumentException('An image element must be provided.');
}
this.reset();
const element = this.prepareImageElement(source);
this.imageElement = element;
let task;
if (this.isImageLoaded(element)) {
task = this.decodeOnce(element, false, true);
}
else {
task = this._decodeOnLoadImage(element);
}
return task;
}
/**
* Decodes something from an image HTML element.
*/
decodeFromVideoElement(source) {
const element = this._decodeFromVideoElementSetup(source);
return this._decodeOnLoadVideo(element);
}
/**
* Decodes something from an image HTML element.
*/
decodeFromVideoElementContinuously(source, callbackFn) {
const element = this._decodeFromVideoElementSetup(source);
return this._decodeOnLoadVideoContinuously(element, callbackFn);
}
/**
* Sets up the video source so it can be decoded when loaded.
*
* @param source The video source element.
*/
_decodeFromVideoElementSetup(source) {
if (!source) {
throw new ArgumentException('A video element must be provided.');
}
this.reset();
const element = this.prepareVideoElement(source);
// defines the video element before starts decoding
this.videoElement = element;
return element;
}
/**
* Decodes an image from a URL.
*/
decodeFromImageUrl(url) {
if (!url) {
throw new ArgumentException('An URL must be provided.');
}
this.reset();
const element = this.prepareImageElement();
this.imageElement = element;
const decodeTask = this._decodeOnLoadImage(element);
element.src = url;
return decodeTask;
}
/**
* Decodes an image from a URL.
*/
decodeFromVideoUrl(url) {
if (!url) {
throw new ArgumentException('An URL must be provided.');
}
this.reset();
// creates a new element
const element = this.prepareVideoElement();
const decodeTask = this.decodeFromVideoElement(element);
element.src = url;
return decodeTask;
}
/**
* Decodes an image from a URL.
*
* @experimental
*/
decodeFromVideoUrlContinuously(url, callbackFn) {
if (!url) {
throw new ArgumentException('An URL must be provided.');
}
this.reset();
// creates a new element
const element = this.prepareVideoElement();
const decodeTask = this.decodeFromVideoElementContinuously(element, callbackFn);
element.src = url;
return decodeTask;
}
_decodeOnLoadImage(element) {
return new Promise((resolve, reject) => {
this.imageLoadedListener = () => this.decodeOnce(element, false, true).then(resolve, reject);
element.addEventListener('load', this.imageLoadedListener);
});
}
_decodeOnLoadVideo(videoElement) {
return __awaiter(this, void 0, void 0, function* () {
// plays the video
yield this.playVideoOnLoadAsync(videoElement);
// starts decoding after played the video
return yield this.decodeOnce(videoElement);
});
}
_decodeOnLoadVideoContinuously(videoElement, callbackFn) {
return __awaiter(this, void 0, void 0, function* () {
// plays the video
yield this.playVideoOnLoadAsync(videoElement);
// starts decoding after played the video
this.decodeContinuously(videoElement, callbackFn);
});
}
isImageLoaded(img) {
// During the onload event, IE correctly identifies any images that
// werent downloaded as not complete. Others should too. Gecko-based
// browsers act like NS4 in that they report this incorrectly.
if (!img.complete) {
return false;
}
// However, they do have two very useful properties: naturalWidth and
// naturalHeight. These give the true size of the image. If it failed
// to load, either of these should be zero.
if (img.naturalWidth === 0) {
return false;
}
// No other way of checking: assume its ok.
return true;
}
prepareImageElement(imageSource) {
let imageElement;
if (typeof imageSource === 'undefined') {
imageElement = document.createElement('img');
imageElement.width = 200;
imageElement.height = 200;
}
if (typeof imageSource === 'string') {
imageElement = this.getMediaElement(imageSource, 'img');
}
if (imageSource instanceof HTMLImageElement) {
imageElement = imageSource;
}
return imageElement;
}
/**
* Sets a HTMLVideoElement for scanning or creates a new one.
*
* @param videoSource The HTMLVideoElement to be set.
*/
prepareVideoElement(videoSource) {
let videoElement;
if (!videoSource && typeof document !== 'undefined') {
videoElement = document.createElement('video');
videoElement.width = 200;
videoElement.height = 200;
}
if (typeof videoSource === 'string') {
videoElement = (this.getMediaElement(videoSource, 'video'));
}
if (videoSource instanceof HTMLVideoElement) {
videoElement = videoSource;
}
// Needed for iOS 11
videoElement.setAttribute('autoplay', 'true');
videoElement.setAttribute('muted', 'true');
videoElement.setAttribute('playsinline', 'true');
return videoElement;
}
/**
* Tries to decode from the video input until it finds some value.
*/
decodeOnce(element, retryIfNotFound = true, retryIfChecksumOrFormatError = true) {
this._stopAsyncDecode = false;
const loop = (resolve, reject) => {
if (this._stopAsyncDecode) {
reject(new NotFoundException('Video stream has ended before any code could be detected.'));
this._stopAsyncDecode = undefined;
return;
}
try {
const result = this.decode(element);
resolve(result);
}
catch (e) {
const ifNotFound = retryIfNotFound && e instanceof NotFoundException;
const isChecksumOrFormatError = e instanceof ChecksumException || e instanceof FormatException;
const ifChecksumOrFormat = isChecksumOrFormatError && retryIfChecksumOrFormatError;
if (ifNotFound || ifChecksumOrFormat) {
// trying again
return setTimeout(loop, this._timeBetweenDecodingAttempts, resolve, reject);
}
reject(e);
}
};
return new Promise((resolve, reject) => loop(resolve, reject));
}
/**
* Continuously decodes from video input.
*/
decodeContinuously(element, callbackFn) {
this._stopContinuousDecode = false;
const loop = () => {
if (this._stopContinuousDecode) {
this._stopContinuousDecode = undefined;
return;
}
try {
const result = this.decode(element);
callbackFn(result, null);
setTimeout(loop, this.timeBetweenScansMillis);
}
catch (e) {
callbackFn(null, e);
const isChecksumOrFormatError = e instanceof ChecksumException || e instanceof FormatException;
const isNotFound = e instanceof NotFoundException;
if (isChecksumOrFormatError || isNotFound) {
// trying again
setTimeout(loop, this._timeBetweenDecodingAttempts);
}
}
};
loop();
}
/**
* Gets the BinaryBitmap for ya! (and decodes it)
*/
decode(element) {
// get binary bitmap for decode function
const binaryBitmap = this.createBinaryBitmap(element);
return this.decodeBitmap(binaryBitmap);
}
/**
* Creates a binaryBitmap based in some image source.
*
* @param mediaElement HTML element containing drawable image source.
*/
createBinaryBitmap(mediaElement) {
const ctx = this.getCaptureCanvasContext(mediaElement);
// doing a scan with inverted colors on the second scan should only happen for video elements
let doAutoInvert = false;
if (mediaElement instanceof HTMLVideoElement) {
this.drawFrameOnCanvas(mediaElement);
doAutoInvert = true;
}
else {
this.drawImageOnCanvas(mediaElement);
}
const canvas = this.getCaptureCanvas(mediaElement);
const luminanceSource = new HTMLCanvasElementLuminanceSource(canvas, doAutoInvert);
const hybridBinarizer = new HybridBinarizer(luminanceSource);
return new BinaryBitmap(hybridBinarizer);
}
/**
*
*/
getCaptureCanvasContext(mediaElement) {
if (!this.captureCanvasContext) {
const elem = this.getCaptureCanvas(mediaElement);
let ctx;
try {
ctx = elem.getContext('2d', { willReadFrequently: true });
}
catch (e) {
ctx = elem.getContext('2d');
}
this.captureCanvasContext = ctx;
}
return this.captureCanvasContext;
}
/**
*
*/
getCaptureCanvas(mediaElement) {
if (!this.captureCanvas) {
const elem = this.createCaptureCanvas(mediaElement);
this.captureCanvas = elem;
}
return this.captureCanvas;
}
/**
* Overwriting this allows you to manipulate the next frame in anyway you want before decode.
*/
drawFrameOnCanvas(srcElement, dimensions = {
sx: 0,
sy: 0,
sWidth: srcElement.videoWidth,
sHeight: srcElement.videoHeight,
dx: 0,
dy: 0,
dWidth: srcElement.videoWidth,
dHeight: srcElement.videoHeight,
}, canvasElementContext = this.captureCanvasContext) {
canvasElementContext.drawImage(srcElement, dimensions.sx, dimensions.sy, dimensions.sWidth, dimensions.sHeight, dimensions.dx, dimensions.dy, dimensions.dWidth, dimensions.dHeight);
}
/**
* Ovewriting this allows you to manipulate the snapshot image in anyway you want before decode.
*/
drawImageOnCanvas(srcElement, dimensions = {
sx: 0,
sy: 0,
sWidth: srcElement.naturalWidth,
sHeight: srcElement.naturalHeight,
dx: 0,
dy: 0,
dWidth: srcElement.naturalWidth,
dHeight: srcElement.naturalHeight,
}, canvasElementContext = this.captureCanvasContext) {
canvasElementContext.drawImage(srcElement, dimensions.sx, dimensions.sy, dimensions.sWidth, dimensions.sHeight, dimensions.dx, dimensions.dy, dimensions.dWidth, dimensions.dHeight);
}
/**
* Call the encapsulated readers decode
*/
decodeBitmap(binaryBitmap) {
return this.reader.decode(binaryBitmap, this._hints);
}
/**
* 🖌 Prepares the canvas for capture and scan frames.
*/
createCaptureCanvas(mediaElement) {
if (typeof document === 'undefined') {
this._destroyCaptureCanvas();
return null;
}
const canvasElement = document.createElement('canvas');
let width;
let height;
if (typeof mediaElement !== 'undefined') {
if (mediaElement instanceof HTMLVideoElement) {
width = mediaElement.videoWidth;
height = mediaElement.videoHeight;
}
else if (mediaElement instanceof HTMLImageElement) {
width = mediaElement.naturalWidth || mediaElement.width;
height = mediaElement.naturalHeight || mediaElement.height;
}
}
canvasElement.style.width = width + 'px';
canvasElement.style.height = height + 'px';
canvasElement.width = width;
canvasElement.height = height;
return canvasElement;
}
/**
* Stops the continuous scan and cleans the stream.
*/
stopStreams() {
if (this.stream) {
this.stream.getVideoTracks().forEach(t => t.stop());
this.stream = undefined;
}
if (this._stopAsyncDecode === false) {
this.stopAsyncDecode();
}
if (this._stopContinuousDecode === false) {
this.stopContinuousDecode();
}
}
/**
* Resets the code reader to the initial state. Cancels any ongoing barcode scanning from video or camera.
*
* @memberOf BrowserCodeReader
*/
reset() {
// stops the camera, preview and scan 🔴
this.stopStreams();
// clean and forget about HTML elements
this._destroyVideoElement();
this._destroyImageElement();
this._destroyCaptureCanvas();
}
_destroyVideoElement() {
if (!this.videoElement) {
return;
}
// first gives freedon to the element 🕊
if (typeof this.videoEndedListener !== 'undefined') {
this.videoElement.removeEventListener('ended', this.videoEndedListener);
}
if (typeof this.videoPlayingEventListener !== 'undefined') {
this.videoElement.removeEventListener('playing', this.videoPlayingEventListener);
}
if (typeof this.videoCanPlayListener !== 'undefined') {
this.videoElement.removeEventListener('loadedmetadata', this.videoCanPlayListener);
}
// then forgets about that element 😢
this.cleanVideoSource(this.videoElement);
this.videoElement = undefined;
}
_destroyImageElement() {
if (!this.imageElement) {
return;
}
// first gives freedon to the element 🕊
if (undefined !== this.imageLoadedListener) {
this.imageElement.removeEventListener('load', this.imageLoadedListener);
}
// then forget about that element 😢
this.imageElement.src = undefined;
this.imageElement.removeAttribute('src');
this.imageElement = undefined;
}
/**
* Cleans canvas references 🖌
*/
_destroyCaptureCanvas() {
// then forget about that element 😢
this.captureCanvasContext = undefined;
this.captureCanvas = undefined;
}
/**
* Defines what the videoElement src will be.
*
* @param videoElement
* @param stream
*/
addVideoSource(videoElement, stream) {
// Older browsers may not have `srcObject`
try {
// @note Throws Exception if interrupted by a new loaded request
videoElement.srcObject = stream;
}
catch (err) {
// @note Avoid using this in new browsers, as it is going away.
// @ts-ignore
videoElement.src = URL.createObjectURL(stream);
}
}
/**
* Unbinds a HTML video src property.
*
* @param videoElement
*/
cleanVideoSource(videoElement) {
try {
videoElement.srcObject = null;
}
catch (err) {
videoElement.src = '';
}
this.videoElement.removeAttribute('src');
}
}
@@ -0,0 +1,13 @@
import { BrowserCodeReader } from './BrowserCodeReader';
/**
* @deprecated Moving to @zxing/browser
*
* QR Code reader to use from browser.
*/
export declare class BrowserDatamatrixCodeReader extends BrowserCodeReader {
/**
* Creates an instance of BrowserQRCodeReader.
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
*/
constructor(timeBetweenScansMillis?: number);
}
@@ -0,0 +1,16 @@
import { BrowserCodeReader } from './BrowserCodeReader';
import DataMatrixReader from '../core/datamatrix/DataMatrixReader';
/**
* @deprecated Moving to @zxing/browser
*
* QR Code reader to use from browser.
*/
export class BrowserDatamatrixCodeReader extends BrowserCodeReader {
/**
* Creates an instance of BrowserQRCodeReader.
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
*/
constructor(timeBetweenScansMillis = 500) {
super(new DataMatrixReader(), timeBetweenScansMillis);
}
}
@@ -0,0 +1,14 @@
import { BrowserCodeReader } from './BrowserCodeReader';
import MultiFormatReader from '../core/MultiFormatReader';
import BinaryBitmap from '../core/BinaryBitmap';
import Result from '../core/Result';
import DecodeHintType from '../core/DecodeHintType';
export declare class BrowserMultiFormatReader extends BrowserCodeReader {
protected readonly reader: MultiFormatReader;
constructor(hints?: Map<DecodeHintType, any>, timeBetweenScansMillis?: number);
/**
* Overwrite decodeBitmap to call decodeWithState, which will pay
* attention to the hints set in the constructor function
*/
decodeBitmap(binaryBitmap: BinaryBitmap): Result;
}
+16
View File
@@ -0,0 +1,16 @@
import { BrowserCodeReader } from './BrowserCodeReader';
import MultiFormatReader from '../core/MultiFormatReader';
export class BrowserMultiFormatReader extends BrowserCodeReader {
constructor(hints = null, timeBetweenScansMillis = 500) {
const reader = new MultiFormatReader();
reader.setHints(hints);
super(reader, timeBetweenScansMillis);
}
/**
* Overwrite decodeBitmap to call decodeWithState, which will pay
* attention to the hints set in the constructor function
*/
decodeBitmap(binaryBitmap) {
return this.reader.decodeWithState(binaryBitmap);
}
}
+13
View File
@@ -0,0 +1,13 @@
import { BrowserCodeReader } from './BrowserCodeReader';
/**
* @deprecated Moving to @zxing/browser
*
* QR Code reader to use from browser.
*/
export declare class BrowserPDF417Reader extends BrowserCodeReader {
/**
* Creates an instance of BrowserPDF417Reader.
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
*/
constructor(timeBetweenScansMillis?: number);
}
+16
View File
@@ -0,0 +1,16 @@
import { BrowserCodeReader } from './BrowserCodeReader';
import PDF417Reader from '../core/pdf417/PDF417Reader';
/**
* @deprecated Moving to @zxing/browser
*
* QR Code reader to use from browser.
*/
export class BrowserPDF417Reader extends BrowserCodeReader {
/**
* Creates an instance of BrowserPDF417Reader.
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
*/
constructor(timeBetweenScansMillis = 500) {
super(new PDF417Reader(), timeBetweenScansMillis);
}
}
+13
View File
@@ -0,0 +1,13 @@
import { BrowserCodeReader } from './BrowserCodeReader';
/**
* @deprecated Moving to @zxing/browser
*
* QR Code reader to use from browser.
*/
export declare class BrowserQRCodeReader extends BrowserCodeReader {
/**
* Creates an instance of BrowserQRCodeReader.
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
*/
constructor(timeBetweenScansMillis?: number);
}
+16
View File
@@ -0,0 +1,16 @@
import { BrowserCodeReader } from './BrowserCodeReader';
import QRCodeReader from '../core/qrcode/QRCodeReader';
/**
* @deprecated Moving to @zxing/browser
*
* QR Code reader to use from browser.
*/
export class BrowserQRCodeReader extends BrowserCodeReader {
/**
* Creates an instance of BrowserQRCodeReader.
* @param {number} [timeBetweenScansMillis=500] the time delay between subsequent decode tries
*/
constructor(timeBetweenScansMillis = 500) {
super(new QRCodeReader(), timeBetweenScansMillis);
}
}
+46
View File
@@ -0,0 +1,46 @@
import EncodeHintType from '../core/EncodeHintType';
/**
* @deprecated Moving to @zxing/browser
*/
declare class BrowserQRCodeSvgWriter {
private static readonly QUIET_ZONE_SIZE;
/**
* SVG markup NameSpace
*/
private static readonly SVG_NS;
/**
* Writes and renders a QRCode SVG element.
*
* @param contents
* @param width
* @param height
* @param hints
*/
write(contents: string, width: number, height: number, hints?: Map<EncodeHintType, any>): SVGSVGElement;
/**
* Renders the result and then appends it to the DOM.
*/
writeToDom(containerElement: string | HTMLElement, contents: string, width: number, height: number, hints?: Map<EncodeHintType, any>): void;
/**
* Note that the input matrix uses 0 == white, 1 == black.
* The output matrix uses 0 == black, 255 == white (i.e. an 8 bit greyscale bitmap).
*/
private renderResult;
/**
* Creates a SVG element.
*
* @param w SVG's width attribute
* @param h SVG's height attribute
*/
private createSVGElement;
/**
* Creates a SVG rect element.
*
* @param x Element's x coordinate
* @param y Element's y coordinate
* @param w Element's width attribute
* @param h Element's height attribute
*/
private createSvgRectElement;
}
export { BrowserQRCodeSvgWriter };
+121
View File
@@ -0,0 +1,121 @@
import EncodeHintType from '../core/EncodeHintType';
import Encoder from '../core/qrcode/encoder/Encoder';
import ErrorCorrectionLevel from '../core/qrcode/decoder/ErrorCorrectionLevel';
import IllegalArgumentException from '../core/IllegalArgumentException';
import IllegalStateException from '../core/IllegalStateException';
/**
* @deprecated Moving to @zxing/browser
*/
class BrowserQRCodeSvgWriter {
/**
* Writes and renders a QRCode SVG element.
*
* @param contents
* @param width
* @param height
* @param hints
*/
write(contents, width, height, hints = null) {
if (contents.length === 0) {
throw new IllegalArgumentException('Found empty contents');
}
// if (format != BarcodeFormat.QR_CODE) {
// throw new IllegalArgumentException("Can only encode QR_CODE, but got " + format)
// }
if (width < 0 || height < 0) {
throw new IllegalArgumentException('Requested dimensions are too small: ' + width + 'x' + height);
}
let errorCorrectionLevel = ErrorCorrectionLevel.L;
let quietZone = BrowserQRCodeSvgWriter.QUIET_ZONE_SIZE;
if (hints !== null) {
if (undefined !== hints.get(EncodeHintType.ERROR_CORRECTION)) {
errorCorrectionLevel = ErrorCorrectionLevel.fromString(hints.get(EncodeHintType.ERROR_CORRECTION).toString());
}
if (undefined !== hints.get(EncodeHintType.MARGIN)) {
quietZone = Number.parseInt(hints.get(EncodeHintType.MARGIN).toString(), 10);
}
}
const code = Encoder.encode(contents, errorCorrectionLevel, hints);
return this.renderResult(code, width, height, quietZone);
}
/**
* Renders the result and then appends it to the DOM.
*/
writeToDom(containerElement, contents, width, height, hints = null) {
if (typeof containerElement === 'string') {
containerElement = document.querySelector(containerElement);
}
const svgElement = this.write(contents, width, height, hints);
if (containerElement)
containerElement.appendChild(svgElement);
}
/**
* Note that the input matrix uses 0 == white, 1 == black.
* The output matrix uses 0 == black, 255 == white (i.e. an 8 bit greyscale bitmap).
*/
renderResult(code, width /*int*/, height /*int*/, quietZone /*int*/) {
const input = code.getMatrix();
if (input === null) {
throw new IllegalStateException();
}
const inputWidth = input.getWidth();
const inputHeight = input.getHeight();
const qrWidth = inputWidth + (quietZone * 2);
const qrHeight = inputHeight + (quietZone * 2);
const outputWidth = Math.max(width, qrWidth);
const outputHeight = Math.max(height, qrHeight);
const multiple = Math.min(Math.floor(outputWidth / qrWidth), Math.floor(outputHeight / qrHeight));
// Padding includes both the quiet zone and the extra white pixels to accommodate the requested
// dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone.
// If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will
// handle all the padding from 100x100 (the actual QR) up to 200x160.
const leftPadding = Math.floor((outputWidth - (inputWidth * multiple)) / 2);
const topPadding = Math.floor((outputHeight - (inputHeight * multiple)) / 2);
const svgElement = this.createSVGElement(outputWidth, outputHeight);
for (let inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
// Write the contents of this row of the barcode
for (let inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
if (input.get(inputX, inputY) === 1) {
const svgRectElement = this.createSvgRectElement(outputX, outputY, multiple, multiple);
svgElement.appendChild(svgRectElement);
}
}
}
return svgElement;
}
/**
* Creates a SVG element.
*
* @param w SVG's width attribute
* @param h SVG's height attribute
*/
createSVGElement(w, h) {
const svgElement = document.createElementNS(BrowserQRCodeSvgWriter.SVG_NS, 'svg');
svgElement.setAttributeNS(null, 'height', w.toString());
svgElement.setAttributeNS(null, 'width', h.toString());
return svgElement;
}
/**
* Creates a SVG rect element.
*
* @param x Element's x coordinate
* @param y Element's y coordinate
* @param w Element's width attribute
* @param h Element's height attribute
*/
createSvgRectElement(x, y, w, h) {
const rect = document.createElementNS(BrowserQRCodeSvgWriter.SVG_NS, 'rect');
rect.setAttributeNS(null, 'x', x.toString());
rect.setAttributeNS(null, 'y', y.toString());
rect.setAttributeNS(null, 'height', w.toString());
rect.setAttributeNS(null, 'width', h.toString());
rect.setAttributeNS(null, 'fill', '#000000');
return rect;
}
}
BrowserQRCodeSvgWriter.QUIET_ZONE_SIZE = 4;
/**
* SVG markup NameSpace
*/
BrowserQRCodeSvgWriter.SVG_NS = 'http://www.w3.org/2000/svg';
export { BrowserQRCodeSvgWriter };
+49
View File
@@ -0,0 +1,49 @@
import EncodeHintType from '../core/EncodeHintType';
/**
* @deprecated Moving to @zxing/browser
*/
declare abstract class BrowserSvgCodeWriter {
/**
* Default quiet zone in pixels.
*/
private static readonly QUIET_ZONE_SIZE;
/**
* SVG markup NameSpace
*/
private static readonly SVG_NS;
/**
* A HTML container element for the image.
*/
private containerElement;
/**
* Constructs. 😉
*/
constructor(containerElement: string | HTMLElement);
/**
* Writes the QR code to a SVG and renders it in the container.
*/
write(contents: string, width: number, height: number, hints?: Map<EncodeHintType, any>): SVGSVGElement;
/**
* Encodes the content to a Barcode type.
*/
private encode;
/**
* Renders the SVG in the container.
*
* @note the input matrix uses 0 == white, 1 == black. The output matrix uses 0 == black, 255 == white (i.e. an 8 bit greyscale bitmap).
*/
private renderResult;
/**
* Creates a SVG element.
*/
protected createSVGElement(w: number, h: number): SVGSVGElement;
/**
* Creates a SVG rect.
*/
protected createSvgPathPlaceholderElement(w: number, h: number): SVGPathElement;
/**
* Creates a SVG rect.
*/
protected createSvgRectElement(x: number, y: number, w: number, h: number): SVGRectElement;
}
export { BrowserSvgCodeWriter };
+129
View File
@@ -0,0 +1,129 @@
import EncodeHintType from '../core/EncodeHintType';
import Encoder from '../core/qrcode/encoder/Encoder';
import ErrorCorrectionLevel from '../core/qrcode/decoder/ErrorCorrectionLevel';
import IllegalArgumentException from '../core/IllegalArgumentException';
import IllegalStateException from '../core/IllegalStateException';
/**
* @deprecated Moving to @zxing/browser
*/
class BrowserSvgCodeWriter {
/**
* Constructs. 😉
*/
constructor(containerElement) {
if (typeof containerElement === 'string') {
this.containerElement = document.getElementById(containerElement);
}
else {
this.containerElement = containerElement;
}
}
/**
* Writes the QR code to a SVG and renders it in the container.
*/
write(contents, width, height, hints = null) {
if (contents.length === 0) {
throw new IllegalArgumentException('Found empty contents');
}
if (width < 0 || height < 0) {
throw new IllegalArgumentException('Requested dimensions are too small: ' + width + 'x' + height);
}
let quietZone = hints && hints.get(EncodeHintType.MARGIN) !== undefined
? Number.parseInt(hints.get(EncodeHintType.MARGIN).toString(), 10)
: BrowserSvgCodeWriter.QUIET_ZONE_SIZE;
const code = this.encode(hints, contents);
return this.renderResult(code, width, height, quietZone);
}
/**
* Encodes the content to a Barcode type.
*/
encode(hints, contents) {
let errorCorrectionLevel = ErrorCorrectionLevel.L;
if (hints && hints.get(EncodeHintType.ERROR_CORRECTION) !== undefined) {
errorCorrectionLevel = ErrorCorrectionLevel.fromString(hints.get(EncodeHintType.ERROR_CORRECTION).toString());
}
const code = Encoder.encode(contents, errorCorrectionLevel, hints);
return code;
}
/**
* Renders the SVG in the container.
*
* @note the input matrix uses 0 == white, 1 == black. The output matrix uses 0 == black, 255 == white (i.e. an 8 bit greyscale bitmap).
*/
renderResult(code, width /*int*/, height /*int*/, quietZone /*int*/) {
// if (this.format && format != this.format) {
// throw new IllegalArgumentException("Can only encode QR_CODE, but got " + format)
// }
const input = code.getMatrix();
if (input === null) {
throw new IllegalStateException();
}
const inputWidth = input.getWidth();
const inputHeight = input.getHeight();
const qrWidth = inputWidth + (quietZone * 2);
const qrHeight = inputHeight + (quietZone * 2);
const outputWidth = Math.max(width, qrWidth);
const outputHeight = Math.max(height, qrHeight);
const multiple = Math.min(Math.floor(outputWidth / qrWidth), Math.floor(outputHeight / qrHeight));
// Padding includes both the quiet zone and the extra white pixels to accommodate the requested
// dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone.
// If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will
// handle all the padding from 100x100 (the actual QR) up to 200x160.
const leftPadding = Math.floor((outputWidth - (inputWidth * multiple)) / 2);
const topPadding = Math.floor((outputHeight - (inputHeight * multiple)) / 2);
const svgElement = this.createSVGElement(outputWidth, outputHeight);
const placeholder = this.createSvgPathPlaceholderElement(width, height);
svgElement.append(placeholder);
this.containerElement.appendChild(svgElement);
// 2D loop
for (let inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
// Write the contents of this row of the barcode
for (let inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
if (input.get(inputX, inputY) === 1) {
const svgRectElement = this.createSvgRectElement(outputX, outputY, multiple, multiple);
svgElement.appendChild(svgRectElement);
}
}
}
return svgElement;
}
/**
* Creates a SVG element.
*/
createSVGElement(w, h) {
const el = document.createElementNS(BrowserSvgCodeWriter.SVG_NS, 'svg');
el.setAttributeNS(null, 'width', h.toString());
el.setAttributeNS(null, 'height', w.toString());
return el;
}
/**
* Creates a SVG rect.
*/
createSvgPathPlaceholderElement(w, h) {
const el = document.createElementNS(BrowserSvgCodeWriter.SVG_NS, 'path');
el.setAttributeNS(null, 'd', `M0 0h${w}v${h}H0z`);
el.setAttributeNS(null, 'fill', 'none');
return el;
}
/**
* Creates a SVG rect.
*/
createSvgRectElement(x, y, w, h) {
const el = document.createElementNS(BrowserSvgCodeWriter.SVG_NS, 'rect');
el.setAttributeNS(null, 'x', x.toString());
el.setAttributeNS(null, 'y', y.toString());
el.setAttributeNS(null, 'height', w.toString());
el.setAttributeNS(null, 'width', h.toString());
el.setAttributeNS(null, 'fill', '#000000');
return el;
}
}
/**
* Default quiet zone in pixels.
*/
BrowserSvgCodeWriter.QUIET_ZONE_SIZE = 4;
/**
* SVG markup NameSpace
*/
BrowserSvgCodeWriter.SVG_NS = 'http://www.w3.org/2000/svg';
export { BrowserSvgCodeWriter };
@@ -0,0 +1,6 @@
import Exception from '../core/Exception';
import Result from '../core/Result';
/**
* Callback format for continuous decode scan.
*/
export declare type DecodeContinuouslyCallback = (result: Result, error?: Exception) => any;
@@ -0,0 +1,29 @@
import LuminanceSource from '../core/LuminanceSource';
/**
* @deprecated Moving to @zxing/browser
*/
export declare class HTMLCanvasElementLuminanceSource extends LuminanceSource {
private canvas;
private buffer;
private static DEGREE_TO_RADIANS;
private static FRAME_INDEX;
private tempCanvasElement;
constructor(canvas: HTMLCanvasElement, doAutoInvert?: boolean);
private static makeBufferFromCanvasImageData;
private static toGrayscaleBuffer;
getRow(y: number, row: Uint8ClampedArray): Uint8ClampedArray;
getMatrix(): Uint8ClampedArray;
isCropSupported(): boolean;
crop(left: number, top: number, width: number, height: number): LuminanceSource;
/**
* This is always true, since the image is a gray-scale image.
*
* @return true
*/
isRotateSupported(): boolean;
rotateCounterClockwise(): LuminanceSource;
rotateCounterClockwise45(): LuminanceSource;
private getTempCanvasElement;
private rotate;
invert(): LuminanceSource;
}
@@ -0,0 +1,150 @@
import InvertedLuminanceSource from '../core/InvertedLuminanceSource';
import LuminanceSource from '../core/LuminanceSource';
import IllegalArgumentException from '../core/IllegalArgumentException';
/**
* @deprecated Moving to @zxing/browser
*/
export class HTMLCanvasElementLuminanceSource extends LuminanceSource {
constructor(canvas, doAutoInvert = false) {
super(canvas.width, canvas.height);
this.canvas = canvas;
this.tempCanvasElement = null;
this.buffer = HTMLCanvasElementLuminanceSource.makeBufferFromCanvasImageData(canvas, doAutoInvert);
}
static makeBufferFromCanvasImageData(canvas, doAutoInvert = false) {
const imageData = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
return HTMLCanvasElementLuminanceSource.toGrayscaleBuffer(imageData.data, canvas.width, canvas.height, doAutoInvert);
}
static toGrayscaleBuffer(imageBuffer, width, height, doAutoInvert = false) {
const grayscaleBuffer = new Uint8ClampedArray(width * height);
HTMLCanvasElementLuminanceSource.FRAME_INDEX = !HTMLCanvasElementLuminanceSource.FRAME_INDEX;
if (HTMLCanvasElementLuminanceSource.FRAME_INDEX || !doAutoInvert) {
for (let i = 0, j = 0, length = imageBuffer.length; i < length; i += 4, j++) {
let gray;
const 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 {
const pixelR = imageBuffer[i];
const pixelG = imageBuffer[i + 1];
const 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.
gray = (306 * pixelR +
601 * pixelG +
117 * pixelB +
0x200) >> 10;
}
grayscaleBuffer[j] = gray;
}
}
else {
for (let i = 0, j = 0, length = imageBuffer.length; i < length; i += 4, j++) {
let gray;
const 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 {
const pixelR = imageBuffer[i];
const pixelG = imageBuffer[i + 1];
const 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.
gray = (306 * pixelR +
601 * pixelG +
117 * pixelB +
0x200) >> 10;
}
grayscaleBuffer[j] = 0xFF - gray;
}
}
return grayscaleBuffer;
}
getRow(y /*int*/, row) {
if (y < 0 || y >= this.getHeight()) {
throw new IllegalArgumentException('Requested row is outside the image: ' + y);
}
const width = this.getWidth();
const 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;
}
getMatrix() {
return this.buffer;
}
isCropSupported() {
return true;
}
crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
super.crop(left, top, width, height);
return this;
}
/**
* This is always true, since the image is a gray-scale image.
*
* @return true
*/
isRotateSupported() {
return true;
}
rotateCounterClockwise() {
this.rotate(-90);
return this;
}
rotateCounterClockwise45() {
this.rotate(-45);
return this;
}
getTempCanvasElement() {
if (null === this.tempCanvasElement) {
const tempCanvasElement = this.canvas.ownerDocument.createElement('canvas');
tempCanvasElement.width = this.canvas.width;
tempCanvasElement.height = this.canvas.height;
this.tempCanvasElement = tempCanvasElement;
}
return this.tempCanvasElement;
}
rotate(angle) {
const tempCanvasElement = this.getTempCanvasElement();
const tempContext = tempCanvasElement.getContext('2d');
const angleRadians = angle * HTMLCanvasElementLuminanceSource.DEGREE_TO_RADIANS;
// Calculate and set new dimensions for temp canvas
const width = this.canvas.width;
const height = this.canvas.height;
const newWidth = Math.ceil(Math.abs(Math.cos(angleRadians)) * width + Math.abs(Math.sin(angleRadians)) * height);
const newHeight = Math.ceil(Math.abs(Math.sin(angleRadians)) * width + Math.abs(Math.cos(angleRadians)) * height);
tempCanvasElement.width = newWidth;
tempCanvasElement.height = newHeight;
// 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;
}
invert() {
return new InvertedLuminanceSource(this);
}
}
HTMLCanvasElementLuminanceSource.DEGREE_TO_RADIANS = Math.PI / 180;
HTMLCanvasElementLuminanceSource.FRAME_INDEX = true;
@@ -0,0 +1,4 @@
/**
* HTML elements that can be decoded.
*/
export declare type HTMLVisualMediaElement = HTMLVideoElement | HTMLImageElement;
+27
View File
@@ -0,0 +1,27 @@
/**
* @deprecated Moving to @zxing/browser
*
* Video input device metadata containing the id and label of the device if available.
*/
export declare class VideoInputDevice implements MediaDeviceInfo {
deviceId: string;
label: string;
/** @inheritdoc */
readonly kind = "videoinput";
/** @inheritdoc */
readonly groupId: string;
/**
* Creates an instance of VideoInputDevice.
*
* @param {string} deviceId the video input device id
* @param {string} label the label of the device if available
*/
constructor(deviceId: string, label: string, groupId?: string);
/** @inheritdoc */
toJSON(): {
kind: string;
groupId: string;
deviceId: string;
label: string;
};
}
+29
View File
@@ -0,0 +1,29 @@
/**
* @deprecated Moving to @zxing/browser
*
* Video input device metadata containing the id and label of the device if available.
*/
export class VideoInputDevice {
/**
* Creates an instance of VideoInputDevice.
*
* @param {string} deviceId the video input device id
* @param {string} label the label of the device if available
*/
constructor(deviceId, label, groupId) {
this.deviceId = deviceId;
this.label = label;
/** @inheritdoc */
this.kind = 'videoinput';
this.groupId = groupId || undefined;
}
/** @inheritdoc */
toJSON() {
return {
kind: this.kind,
groupId: this.groupId,
deviceId: this.deviceId,
label: this.label,
};
}
}
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class ArgumentException extends Exception {
static readonly kind: string;
}
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class ArgumentException extends Exception {
}
ArgumentException.kind = 'ArgumentException';
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class ArithmeticException extends Exception {
static readonly kind: string;
}
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class ArithmeticException extends Exception {
}
ArithmeticException.kind = 'ArithmeticException';
@@ -0,0 +1,10 @@
import IndexOutOfBoundsException from './IndexOutOfBoundsException';
/**
* Custom Error class of type Exception.
*/
export default class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
index: number;
message: string;
static readonly kind: string;
constructor(index?: number, message?: string);
}
@@ -0,0 +1,12 @@
import IndexOutOfBoundsException from './IndexOutOfBoundsException';
/**
* Custom Error class of type Exception.
*/
export default class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
constructor(index = undefined, message = undefined) {
super(message);
this.index = index;
this.message = message;
}
}
ArrayIndexOutOfBoundsException.kind = 'ArrayIndexOutOfBoundsException';
+42
View File
@@ -0,0 +1,42 @@
/**
* Enumerates barcode formats known to this package. Please keep alphabetized.
*
* @author Sean Owen
*/
declare enum BarcodeFormat {
/** Aztec 2D barcode format. */
AZTEC = 0,
/** CODABAR 1D format. */
CODABAR = 1,
/** Code 39 1D format. */
CODE_39 = 2,
/** Code 93 1D format. */
CODE_93 = 3,
/** Code 128 1D format. */
CODE_128 = 4,
/** Data Matrix 2D barcode format. */
DATA_MATRIX = 5,
/** EAN-8 1D format. */
EAN_8 = 6,
/** EAN-13 1D format. */
EAN_13 = 7,
/** ITF (Interleaved Two of Five) 1D format. */
ITF = 8,
/** MaxiCode 2D barcode format. */
MAXICODE = 9,
/** PDF417 format. */
PDF_417 = 10,
/** QR Code 2D barcode format. */
QR_CODE = 11,
/** RSS 14 */
RSS_14 = 12,
/** RSS EXPANDED */
RSS_EXPANDED = 13,
/** UPC-A 1D format. */
UPC_A = 14,
/** UPC-E 1D format. */
UPC_E = 15,
/** UPC/EAN extension format. Not a stand-alone format. */
UPC_EAN_EXTENSION = 16
}
export default BarcodeFormat;
+62
View File
@@ -0,0 +1,62 @@
/*
* Direct port to TypeScript of ZXing by Adrian Toșcă
*/
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*namespace com.google.zxing {*/
/**
* Enumerates barcode formats known to this package. Please keep alphabetized.
*
* @author Sean Owen
*/
var BarcodeFormat;
(function (BarcodeFormat) {
/** Aztec 2D barcode format. */
BarcodeFormat[BarcodeFormat["AZTEC"] = 0] = "AZTEC";
/** CODABAR 1D format. */
BarcodeFormat[BarcodeFormat["CODABAR"] = 1] = "CODABAR";
/** Code 39 1D format. */
BarcodeFormat[BarcodeFormat["CODE_39"] = 2] = "CODE_39";
/** Code 93 1D format. */
BarcodeFormat[BarcodeFormat["CODE_93"] = 3] = "CODE_93";
/** Code 128 1D format. */
BarcodeFormat[BarcodeFormat["CODE_128"] = 4] = "CODE_128";
/** Data Matrix 2D barcode format. */
BarcodeFormat[BarcodeFormat["DATA_MATRIX"] = 5] = "DATA_MATRIX";
/** EAN-8 1D format. */
BarcodeFormat[BarcodeFormat["EAN_8"] = 6] = "EAN_8";
/** EAN-13 1D format. */
BarcodeFormat[BarcodeFormat["EAN_13"] = 7] = "EAN_13";
/** ITF (Interleaved Two of Five) 1D format. */
BarcodeFormat[BarcodeFormat["ITF"] = 8] = "ITF";
/** MaxiCode 2D barcode format. */
BarcodeFormat[BarcodeFormat["MAXICODE"] = 9] = "MAXICODE";
/** PDF417 format. */
BarcodeFormat[BarcodeFormat["PDF_417"] = 10] = "PDF_417";
/** QR Code 2D barcode format. */
BarcodeFormat[BarcodeFormat["QR_CODE"] = 11] = "QR_CODE";
/** RSS 14 */
BarcodeFormat[BarcodeFormat["RSS_14"] = 12] = "RSS_14";
/** RSS EXPANDED */
BarcodeFormat[BarcodeFormat["RSS_EXPANDED"] = 13] = "RSS_EXPANDED";
/** UPC-A 1D format. */
BarcodeFormat[BarcodeFormat["UPC_A"] = 14] = "UPC_A";
/** UPC-E 1D format. */
BarcodeFormat[BarcodeFormat["UPC_E"] = 15] = "UPC_E";
/** UPC/EAN extension format. Not a stand-alone format. */
BarcodeFormat[BarcodeFormat["UPC_EAN_EXTENSION"] = 16] = "UPC_EAN_EXTENSION";
})(BarcodeFormat || (BarcodeFormat = {}));
export default BarcodeFormat;
+53
View File
@@ -0,0 +1,53 @@
import LuminanceSource from './LuminanceSource';
import BitArray from './common/BitArray';
import BitMatrix from './common/BitMatrix';
/**
* This class hierarchy provides a set of methods to convert luminance data to 1 bit data.
* It allows the algorithm to vary polymorphically, for example allowing a very expensive
* thresholding technique for servers and a fast one for mobile. It also permits the implementation
* to vary, e.g. a JNI version for Android and a Java fallback version for other platforms.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
declare abstract class Binarizer {
private source;
protected constructor(source: LuminanceSource);
getLuminanceSource(): LuminanceSource;
/**
* Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
* cached data. Callers should assume this method is expensive and call it as seldom as possible.
* This method is intended for decoding 1D barcodes and may choose to apply sharpening.
* For callers which only examine one row of pixels at a time, the same BitArray should be reused
* and passed in with each call for performance. However it is legal to keep more than one row
* at a time if needed.
*
* @param y The row to fetch, which must be in [0, bitmap height)
* @param row An optional preallocated array. If null or too small, it will be ignored.
* If used, the Binarizer will call BitArray.clear(). Always use the returned object.
* @return The array of bits for this row (true means black).
* @throws NotFoundException if row can't be binarized
*/
abstract getBlackRow(y: number, row: BitArray): BitArray;
/**
* Converts a 2D array of luminance data to 1 bit data. As above, assume this method is expensive
* and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
* may not apply sharpening. Therefore, a row from this matrix may not be identical to one
* fetched using getBlackRow(), so don't mix and match between them.
*
* @return The 2D array of bits for the image (true means black).
* @throws NotFoundException if image can't be binarized to make a matrix
*/
abstract getBlackMatrix(): BitMatrix;
/**
* Creates a new object with the same type as this Binarizer implementation, but with pristine
* state. This is needed because Binarizer implementations may be stateful, e.g. keeping a cache
* of 1 bit data. See Effective Java for why we can't use Java's clone() method.
*
* @param source The LuminanceSource this Binarizer will operate on.
* @return A new concrete Binarizer implementation object.
*/
abstract createBinarizer(source: LuminanceSource): Binarizer;
getWidth(): number;
getHeight(): number;
}
export default Binarizer;
+38
View File
@@ -0,0 +1,38 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This class hierarchy provides a set of methods to convert luminance data to 1 bit data.
* It allows the algorithm to vary polymorphically, for example allowing a very expensive
* thresholding technique for servers and a fast one for mobile. It also permits the implementation
* to vary, e.g. a JNI version for Android and a Java fallback version for other platforms.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
class Binarizer {
constructor(source) {
this.source = source;
}
getLuminanceSource() {
return this.source;
}
getWidth() {
return this.source.getWidth();
}
getHeight() {
return this.source.getHeight();
}
}
export default Binarizer;
+78
View File
@@ -0,0 +1,78 @@
/**
* This class is the core bitmap class used by ZXing to represent 1 bit data. Reader objects
* accept a BinaryBitmap and attempt to decode it.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
import Binarizer from './Binarizer';
import BitArray from './common/BitArray';
import BitMatrix from './common/BitMatrix';
export default class BinaryBitmap {
private binarizer;
private matrix;
constructor(binarizer: Binarizer);
/**
* @return The width of the bitmap.
*/
getWidth(): number;
/**
* @return The height of the bitmap.
*/
getHeight(): number;
/**
* Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
* cached data. Callers should assume this method is expensive and call it as seldom as possible.
* This method is intended for decoding 1D barcodes and may choose to apply sharpening.
*
* @param y The row to fetch, which must be in [0, bitmap height)
* @param row An optional preallocated array. If null or too small, it will be ignored.
* If used, the Binarizer will call BitArray.clear(). Always use the returned object.
* @return The array of bits for this row (true means black).
* @throws NotFoundException if row can't be binarized
*/
getBlackRow(y: number, row: BitArray): BitArray;
/**
* Converts a 2D array of luminance data to 1 bit. As above, assume this method is expensive
* and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
* may not apply sharpening. Therefore, a row from this matrix may not be identical to one
* fetched using getBlackRow(), so don't mix and match between them.
*
* @return The 2D array of bits for the image (true means black).
* @throws NotFoundException if image can't be binarized to make a matrix
*/
getBlackMatrix(): BitMatrix;
/**
* @return Whether this bitmap can be cropped.
*/
isCropSupported(): boolean;
/**
* Returns a new object with cropped image data. Implementations may keep a reference to the
* original data rather than a copy. Only callable if isCropSupported() is true.
*
* @param left The left coordinate, which must be in [0,getWidth())
* @param top The top coordinate, which must be in [0,getHeight())
* @param width The width of the rectangle to crop.
* @param height The height of the rectangle to crop.
* @return A cropped version of this object.
*/
crop(left: number, top: number, width: number, height: number): BinaryBitmap;
/**
* @return Whether this bitmap supports counter-clockwise rotation.
*/
isRotateSupported(): boolean;
/**
* Returns a new object with rotated image data by 90 degrees counterclockwise.
* Only callable if {@link #isRotateSupported()} is true.
*
* @return A rotated version of this object.
*/
rotateCounterClockwise(): BinaryBitmap;
/**
* Returns a new object with rotated image data by 45 degrees counterclockwise.
* Only callable if {@link #isRotateSupported()} is true.
*
* @return A rotated version of this object.
*/
rotateCounterClockwise45(): BinaryBitmap;
toString(): string;
}
+125
View File
@@ -0,0 +1,125 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import IllegalArgumentException from './IllegalArgumentException';
export default class BinaryBitmap {
constructor(binarizer) {
this.binarizer = binarizer;
if (binarizer === null) {
throw new IllegalArgumentException('Binarizer must be non-null.');
}
}
/**
* @return The width of the bitmap.
*/
getWidth() {
return this.binarizer.getWidth();
}
/**
* @return The height of the bitmap.
*/
getHeight() {
return this.binarizer.getHeight();
}
/**
* Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
* cached data. Callers should assume this method is expensive and call it as seldom as possible.
* This method is intended for decoding 1D barcodes and may choose to apply sharpening.
*
* @param y The row to fetch, which must be in [0, bitmap height)
* @param row An optional preallocated array. If null or too small, it will be ignored.
* If used, the Binarizer will call BitArray.clear(). Always use the returned object.
* @return The array of bits for this row (true means black).
* @throws NotFoundException if row can't be binarized
*/
getBlackRow(y /*int*/, row) {
return this.binarizer.getBlackRow(y, row);
}
/**
* Converts a 2D array of luminance data to 1 bit. As above, assume this method is expensive
* and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
* may not apply sharpening. Therefore, a row from this matrix may not be identical to one
* fetched using getBlackRow(), so don't mix and match between them.
*
* @return The 2D array of bits for the image (true means black).
* @throws NotFoundException if image can't be binarized to make a matrix
*/
getBlackMatrix() {
// The matrix is created on demand the first time it is requested, then cached. There are two
// reasons for this:
// 1. This work will never be done if the caller only installs 1D Reader objects, or if a
// 1D Reader finds a barcode before the 2D Readers run.
// 2. This work will only be done once even if the caller installs multiple 2D Readers.
if (this.matrix === null || this.matrix === undefined) {
this.matrix = this.binarizer.getBlackMatrix();
}
return this.matrix;
}
/**
* @return Whether this bitmap can be cropped.
*/
isCropSupported() {
return this.binarizer.getLuminanceSource().isCropSupported();
}
/**
* Returns a new object with cropped image data. Implementations may keep a reference to the
* original data rather than a copy. Only callable if isCropSupported() is true.
*
* @param left The left coordinate, which must be in [0,getWidth())
* @param top The top coordinate, which must be in [0,getHeight())
* @param width The width of the rectangle to crop.
* @param height The height of the rectangle to crop.
* @return A cropped version of this object.
*/
crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
const newSource = this.binarizer.getLuminanceSource().crop(left, top, width, height);
return new BinaryBitmap(this.binarizer.createBinarizer(newSource));
}
/**
* @return Whether this bitmap supports counter-clockwise rotation.
*/
isRotateSupported() {
return this.binarizer.getLuminanceSource().isRotateSupported();
}
/**
* Returns a new object with rotated image data by 90 degrees counterclockwise.
* Only callable if {@link #isRotateSupported()} is true.
*
* @return A rotated version of this object.
*/
rotateCounterClockwise() {
const newSource = this.binarizer.getLuminanceSource().rotateCounterClockwise();
return new BinaryBitmap(this.binarizer.createBinarizer(newSource));
}
/**
* Returns a new object with rotated image data by 45 degrees counterclockwise.
* Only callable if {@link #isRotateSupported()} is true.
*
* @return A rotated version of this object.
*/
rotateCounterClockwise45() {
const newSource = this.binarizer.getLuminanceSource().rotateCounterClockwise45();
return new BinaryBitmap(this.binarizer.createBinarizer(newSource));
}
/*@Override*/
toString() {
try {
return this.getBlackMatrix().toString();
}
catch (e /*: NotFoundException*/) {
return '';
}
}
}
+8
View File
@@ -0,0 +1,8 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class ChecksumException extends Exception {
static readonly kind: string;
static getChecksumInstance(): ChecksumException;
}
+10
View File
@@ -0,0 +1,10 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class ChecksumException extends Exception {
static getChecksumInstance() {
return new ChecksumException();
}
}
ChecksumException.kind = 'ChecksumException';
+74
View File
@@ -0,0 +1,74 @@
/**
* Encapsulates a type of hint that a caller may pass to a barcode reader to help it
* more quickly or accurately decode it. It is up to implementations to decide what,
* if anything, to do with the information that is supplied.
*
* @author Sean Owen
* @author dswitkin@google.com (Daniel Switkin)
* @see Reader#decode(BinaryBitmap,java.util.Map)
*/
declare enum DecodeHintType {
/**
* Unspecified, application-specific hint. Maps to an unspecified {@link Object}.
*/
OTHER = 0,
/**
* Image is a pure monochrome image of a barcode. Doesn't matter what it maps to;
* use {@link Boolean#TRUE}.
*/
PURE_BARCODE = 1,
/**
* Image is known to be of one of a few possible formats.
* Maps to a {@link List} of {@link BarcodeFormat}s.
*/
POSSIBLE_FORMATS = 2,
/**
* Spend more time to try to find a barcode; optimize for accuracy, not speed.
* Doesn't matter what it maps to; use {@link Boolean#TRUE}.
*/
TRY_HARDER = 3,
/**
* Specifies what character encoding to use when decoding, where applicable (type String)
*/
CHARACTER_SET = 4,
/**
* Allowed lengths of encoded data -- reject anything else. Maps to an {@code Int32Array}.
*/
ALLOWED_LENGTHS = 5,
/**
* Assume Code 39 codes employ a check digit. Doesn't matter what it maps to;
* use {@link Boolean#TRUE}.
*/
ASSUME_CODE_39_CHECK_DIGIT = 6,
/**
* Enable extended mode for Code 39 codes. Doesn't matter what it maps to;
* use {@link Boolean#TRUE}.
*/
ENABLE_CODE_39_EXTENDED_MODE = 7,
/**
* Assume the barcode is being processed as a GS1 barcode, and modify behavior as needed.
* For example this affects FNC1 handling for Code 128 (aka GS1-128). Doesn't matter what it maps to;
* use {@link Boolean#TRUE}.
*/
ASSUME_GS1 = 8,
/**
* If true, return the start and end digits in a Codabar barcode instead of stripping them. They
* are alpha, whereas the rest are numeric. By default, they are stripped, but this causes them
* to not be. Doesn't matter what it maps to; use {@link Boolean#TRUE}.
*/
RETURN_CODABAR_START_END = 9,
/**
* The caller needs to be notified via callback when a possible {@link ResultPoint}
* is found. Maps to a {@link ResultPointCallback}.
*/
NEED_RESULT_POINT_CALLBACK = 10,
/**
* Allowed extension lengths for EAN or UPC barcodes. Other formats will ignore this.
* Maps to an {@code Int32Array} of the allowed extension lengths, for example [2], [5], or [2, 5].
* If it is optional to have an extension, do not set this hint. If this is set,
* and a UPC or EAN barcode is found but an extension is not, then no result will be returned
* at all.
*/
ALLOWED_EAN_EXTENSIONS = 11
}
export default DecodeHintType;
+107
View File
@@ -0,0 +1,107 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*namespace com.google.zxing {*/
/**
* Encapsulates a type of hint that a caller may pass to a barcode reader to help it
* more quickly or accurately decode it. It is up to implementations to decide what,
* if anything, to do with the information that is supplied.
*
* @author Sean Owen
* @author dswitkin@google.com (Daniel Switkin)
* @see Reader#decode(BinaryBitmap,java.util.Map)
*/
var DecodeHintType;
(function (DecodeHintType) {
/**
* Unspecified, application-specific hint. Maps to an unspecified {@link Object}.
*/
DecodeHintType[DecodeHintType["OTHER"] = 0] = "OTHER"; /*(Object.class)*/
/**
* Image is a pure monochrome image of a barcode. Doesn't matter what it maps to;
* use {@link Boolean#TRUE}.
*/
DecodeHintType[DecodeHintType["PURE_BARCODE"] = 1] = "PURE_BARCODE"; /*(Void.class)*/
/**
* Image is known to be of one of a few possible formats.
* Maps to a {@link List} of {@link BarcodeFormat}s.
*/
DecodeHintType[DecodeHintType["POSSIBLE_FORMATS"] = 2] = "POSSIBLE_FORMATS"; /*(List.class)*/
/**
* Spend more time to try to find a barcode; optimize for accuracy, not speed.
* Doesn't matter what it maps to; use {@link Boolean#TRUE}.
*/
DecodeHintType[DecodeHintType["TRY_HARDER"] = 3] = "TRY_HARDER"; /*(Void.class)*/
/**
* Specifies what character encoding to use when decoding, where applicable (type String)
*/
DecodeHintType[DecodeHintType["CHARACTER_SET"] = 4] = "CHARACTER_SET"; /*(String.class)*/
/**
* Allowed lengths of encoded data -- reject anything else. Maps to an {@code Int32Array}.
*/
DecodeHintType[DecodeHintType["ALLOWED_LENGTHS"] = 5] = "ALLOWED_LENGTHS"; /*(Int32Array.class)*/
/**
* Assume Code 39 codes employ a check digit. Doesn't matter what it maps to;
* use {@link Boolean#TRUE}.
*/
DecodeHintType[DecodeHintType["ASSUME_CODE_39_CHECK_DIGIT"] = 6] = "ASSUME_CODE_39_CHECK_DIGIT"; /*(Void.class)*/
/**
* Enable extended mode for Code 39 codes. Doesn't matter what it maps to;
* use {@link Boolean#TRUE}.
*/
DecodeHintType[DecodeHintType["ENABLE_CODE_39_EXTENDED_MODE"] = 7] = "ENABLE_CODE_39_EXTENDED_MODE"; /*(Void.class)*/
/**
* Assume the barcode is being processed as a GS1 barcode, and modify behavior as needed.
* For example this affects FNC1 handling for Code 128 (aka GS1-128). Doesn't matter what it maps to;
* use {@link Boolean#TRUE}.
*/
DecodeHintType[DecodeHintType["ASSUME_GS1"] = 8] = "ASSUME_GS1"; /*(Void.class)*/
/**
* If true, return the start and end digits in a Codabar barcode instead of stripping them. They
* are alpha, whereas the rest are numeric. By default, they are stripped, but this causes them
* to not be. Doesn't matter what it maps to; use {@link Boolean#TRUE}.
*/
DecodeHintType[DecodeHintType["RETURN_CODABAR_START_END"] = 9] = "RETURN_CODABAR_START_END"; /*(Void.class)*/
/**
* The caller needs to be notified via callback when a possible {@link ResultPoint}
* is found. Maps to a {@link ResultPointCallback}.
*/
DecodeHintType[DecodeHintType["NEED_RESULT_POINT_CALLBACK"] = 10] = "NEED_RESULT_POINT_CALLBACK"; /*(ResultPointCallback.class)*/
/**
* Allowed extension lengths for EAN or UPC barcodes. Other formats will ignore this.
* Maps to an {@code Int32Array} of the allowed extension lengths, for example [2], [5], or [2, 5].
* If it is optional to have an extension, do not set this hint. If this is set,
* and a UPC or EAN barcode is found but an extension is not, then no result will be returned
* at all.
*/
DecodeHintType[DecodeHintType["ALLOWED_EAN_EXTENSIONS"] = 11] = "ALLOWED_EAN_EXTENSIONS"; /*(Int32Array.class)*/
// End of enumeration values.
/**
* Data type the hint is expecting.
* Among the possible values the {@link Void} stands out as being used for
* hints that do not expect a value to be supplied (flag hints). Such hints
* will possibly have their value ignored, or replaced by a
* {@link Boolean#TRUE}. Hint suppliers should probably use
* {@link Boolean#TRUE} as directed by the actual hint documentation.
*/
// private valueType: Class<?>
// DecodeHintType(valueType: Class<?>) {
// this.valueType = valueType
// }
// public getValueType(): Class<?> {
// return valueType
// }
})(DecodeHintType || (DecodeHintType = {}));
export default DecodeHintType;
+13
View File
@@ -0,0 +1,13 @@
/**
* Simply encapsulates a width and height.
*/
export default class Dimension {
private width;
private height;
constructor(width: number, height: number);
getWidth(): number;
getHeight(): number;
equals(other: any): boolean;
hashCode(): number;
toString(): string;
}
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import IllegalArgumentException from './IllegalArgumentException';
/*namespace com.google.zxing {*/
/**
* Simply encapsulates a width and height.
*/
export default class Dimension {
constructor(width /*int*/, height /*int*/) {
this.width = width;
this.height = height;
if (width < 0 || height < 0) {
throw new IllegalArgumentException();
}
}
getWidth() {
return this.width;
}
getHeight() {
return this.height;
}
/*@Override*/
equals(other) {
if (other instanceof Dimension) {
const d = other;
return this.width === d.width && this.height === d.height;
}
return false;
}
/*@Override*/
hashCode() {
return this.width * 32713 + this.height;
}
/*@Override*/
toString() {
return this.width + 'x' + this.height;
}
}
+99
View File
@@ -0,0 +1,99 @@
/**
* These are a set of hints that you may pass to Writers to specify their behavior.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
declare enum EncodeHintType {
/**
* Specifies what degree of error correction to use, for example in QR Codes.
* Type depends on the encoder. For example for QR codes it's type
* {@link com.google.zxing.qrcode.decoder.ErrorCorrectionLevel ErrorCorrectionLevel}.
* For Aztec it is of type {@link Integer}, representing the minimal percentage of error correction words.
* For PDF417 it is of type {@link Integer}, valid values being 0 to 8.
* In all cases, it can also be a {@link String} representation of the desired value as well.
* Note: an Aztec symbol should have a minimum of 25% EC words.
*/
ERROR_CORRECTION = 0,
/**
* Specifies what character encoding to use where applicable (type {@link String})
*/
CHARACTER_SET = 1,
/**
* Specifies the matrix shape for Data Matrix (type {@link com.google.zxing.datamatrix.encoder.SymbolShapeHint})
*/
DATA_MATRIX_SHAPE = 2,
/**
* Specifies whether to use compact mode for Data Matrix (type {@link Boolean}, or "true" or "false"
* {@link String } value).
* The compact encoding mode also supports the encoding of characters that are not in the ISO-8859-1
* character set via ECIs.
* Please note that in that case, the most compact character encoding is chosen for characters in
* the input that are not in the ISO-8859-1 character set. Based on experience, some scanners do not
* support encodings like cp-1256 (Arabic). In such cases the encoding can be forced to UTF-8 by
* means of the {@link #CHARACTER_SET} encoding hint.
* Compact encoding also provides GS1-FNC1 support when {@link #GS1_FORMAT} is selected. In this case
* group-separator character (ASCII 29 decimal) can be used to encode the positions of FNC1 codewords
* for the purpose of delimiting AIs.
* This option and {@link #FORCE_C40} are mutually exclusive.
*/
DATA_MATRIX_COMPACT = 3,
/**
* Specifies a minimum barcode size (type {@link Dimension}). Only applicable to Data Matrix now.
*
* @deprecated use width/height params in
* {@link com.google.zxing.datamatrix.DataMatrixWriter#encode(String, BarcodeFormat, int, int)}
*/
MIN_SIZE = 4,
/**
* Specifies a maximum barcode size (type {@link Dimension}). Only applicable to Data Matrix now.
*
* @deprecated without replacement
*/
MAX_SIZE = 5,
/**
* Specifies margin, in pixels, to use when generating the barcode. The meaning can vary
* by format; for example it controls margin before and after the barcode horizontally for
* most 1D formats. (Type {@link Integer}, or {@link String} representation of the integer value).
*/
MARGIN = 6,
/**
* Specifies whether to use compact mode for PDF417 (type {@link Boolean}, or "true" or "false"
* {@link String} value).
*/
PDF417_COMPACT = 7,
/**
* Specifies what compaction mode to use for PDF417 (type
* {@link com.google.zxing.pdf417.encoder.Compaction Compaction} or {@link String} value of one of its
* enum values).
*/
PDF417_COMPACTION = 8,
/**
* Specifies the minimum and maximum number of rows and columns for PDF417 (type
* {@link com.google.zxing.pdf417.encoder.Dimensions Dimensions}).
*/
PDF417_DIMENSIONS = 9,
/**
* Specifies the required number of layers for an Aztec code.
* A negative number (-1, -2, -3, -4) specifies a compact Aztec code.
* 0 indicates to use the minimum number of layers (the default).
* A positive number (1, 2, .. 32) specifies a normal (non-compact) Aztec code.
* (Type {@link Integer}, or {@link String} representation of the integer value).
*/
AZTEC_LAYERS = 10,
/**
* Specifies the exact version of QR code to be encoded.
* (Type {@link Integer}, or {@link String} representation of the integer value).
*/
QR_VERSION = 11,
/**
* Specifies whether the data should be encoded to the GS1 standard (type {@link Boolean}, or "true" or "false"
* {@link String } value).
*/
GS1_FORMAT = 12,
/**
* Forces C40 encoding for data-matrix (type {@link Boolean}, or "true" or "false") {@link String } value). This
* option and {@link #DATA_MATRIX_COMPACT} are mutually exclusive.
*/
FORCE_C40 = 13
}
export default EncodeHintType;
+118
View File
@@ -0,0 +1,118 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*namespace com.google.zxing {*/
/**
* These are a set of hints that you may pass to Writers to specify their behavior.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
var EncodeHintType;
(function (EncodeHintType) {
/**
* Specifies what degree of error correction to use, for example in QR Codes.
* Type depends on the encoder. For example for QR codes it's type
* {@link com.google.zxing.qrcode.decoder.ErrorCorrectionLevel ErrorCorrectionLevel}.
* For Aztec it is of type {@link Integer}, representing the minimal percentage of error correction words.
* For PDF417 it is of type {@link Integer}, valid values being 0 to 8.
* In all cases, it can also be a {@link String} representation of the desired value as well.
* Note: an Aztec symbol should have a minimum of 25% EC words.
*/
EncodeHintType[EncodeHintType["ERROR_CORRECTION"] = 0] = "ERROR_CORRECTION";
/**
* Specifies what character encoding to use where applicable (type {@link String})
*/
EncodeHintType[EncodeHintType["CHARACTER_SET"] = 1] = "CHARACTER_SET";
/**
* Specifies the matrix shape for Data Matrix (type {@link com.google.zxing.datamatrix.encoder.SymbolShapeHint})
*/
EncodeHintType[EncodeHintType["DATA_MATRIX_SHAPE"] = 2] = "DATA_MATRIX_SHAPE";
/**
* Specifies whether to use compact mode for Data Matrix (type {@link Boolean}, or "true" or "false"
* {@link String } value).
* The compact encoding mode also supports the encoding of characters that are not in the ISO-8859-1
* character set via ECIs.
* Please note that in that case, the most compact character encoding is chosen for characters in
* the input that are not in the ISO-8859-1 character set. Based on experience, some scanners do not
* support encodings like cp-1256 (Arabic). In such cases the encoding can be forced to UTF-8 by
* means of the {@link #CHARACTER_SET} encoding hint.
* Compact encoding also provides GS1-FNC1 support when {@link #GS1_FORMAT} is selected. In this case
* group-separator character (ASCII 29 decimal) can be used to encode the positions of FNC1 codewords
* for the purpose of delimiting AIs.
* This option and {@link #FORCE_C40} are mutually exclusive.
*/
EncodeHintType[EncodeHintType["DATA_MATRIX_COMPACT"] = 3] = "DATA_MATRIX_COMPACT";
/**
* Specifies a minimum barcode size (type {@link Dimension}). Only applicable to Data Matrix now.
*
* @deprecated use width/height params in
* {@link com.google.zxing.datamatrix.DataMatrixWriter#encode(String, BarcodeFormat, int, int)}
*/
/*@Deprecated*/
EncodeHintType[EncodeHintType["MIN_SIZE"] = 4] = "MIN_SIZE";
/**
* Specifies a maximum barcode size (type {@link Dimension}). Only applicable to Data Matrix now.
*
* @deprecated without replacement
*/
/*@Deprecated*/
EncodeHintType[EncodeHintType["MAX_SIZE"] = 5] = "MAX_SIZE";
/**
* Specifies margin, in pixels, to use when generating the barcode. The meaning can vary
* by format; for example it controls margin before and after the barcode horizontally for
* most 1D formats. (Type {@link Integer}, or {@link String} representation of the integer value).
*/
EncodeHintType[EncodeHintType["MARGIN"] = 6] = "MARGIN";
/**
* Specifies whether to use compact mode for PDF417 (type {@link Boolean}, or "true" or "false"
* {@link String} value).
*/
EncodeHintType[EncodeHintType["PDF417_COMPACT"] = 7] = "PDF417_COMPACT";
/**
* Specifies what compaction mode to use for PDF417 (type
* {@link com.google.zxing.pdf417.encoder.Compaction Compaction} or {@link String} value of one of its
* enum values).
*/
EncodeHintType[EncodeHintType["PDF417_COMPACTION"] = 8] = "PDF417_COMPACTION";
/**
* Specifies the minimum and maximum number of rows and columns for PDF417 (type
* {@link com.google.zxing.pdf417.encoder.Dimensions Dimensions}).
*/
EncodeHintType[EncodeHintType["PDF417_DIMENSIONS"] = 9] = "PDF417_DIMENSIONS";
/**
* Specifies the required number of layers for an Aztec code.
* A negative number (-1, -2, -3, -4) specifies a compact Aztec code.
* 0 indicates to use the minimum number of layers (the default).
* A positive number (1, 2, .. 32) specifies a normal (non-compact) Aztec code.
* (Type {@link Integer}, or {@link String} representation of the integer value).
*/
EncodeHintType[EncodeHintType["AZTEC_LAYERS"] = 10] = "AZTEC_LAYERS";
/**
* Specifies the exact version of QR code to be encoded.
* (Type {@link Integer}, or {@link String} representation of the integer value).
*/
EncodeHintType[EncodeHintType["QR_VERSION"] = 11] = "QR_VERSION";
/**
* Specifies whether the data should be encoded to the GS1 standard (type {@link Boolean}, or "true" or "false"
* {@link String } value).
*/
EncodeHintType[EncodeHintType["GS1_FORMAT"] = 12] = "GS1_FORMAT";
/**
* Forces C40 encoding for data-matrix (type {@link Boolean}, or "true" or "false") {@link String } value). This
* option and {@link #DATA_MATRIX_COMPACT} are mutually exclusive.
*/
EncodeHintType[EncodeHintType["FORCE_C40"] = 13] = "FORCE_C40";
})(EncodeHintType || (EncodeHintType = {}));
export default EncodeHintType;
+17
View File
@@ -0,0 +1,17 @@
import { CustomError } from 'ts-custom-error';
/**
* Custom Error class of type Exception.
*/
export default class Exception extends CustomError {
message: string;
/**
* It's typed as string so it can be extended and overriden.
*/
static readonly kind: string;
/**
* Allows Exception to be constructed directly
* with some message and prototype definition.
*/
constructor(message?: string);
getKind(): string;
}
+22
View File
@@ -0,0 +1,22 @@
import { CustomError } from 'ts-custom-error';
/**
* Custom Error class of type Exception.
*/
export default class Exception extends CustomError {
/**
* Allows Exception to be constructed directly
* with some message and prototype definition.
*/
constructor(message = undefined) {
super(message);
this.message = message;
}
getKind() {
const ex = this.constructor;
return ex.kind;
}
}
/**
* It's typed as string so it can be extended and overriden.
*/
Exception.kind = 'Exception';
+8
View File
@@ -0,0 +1,8 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class FormatException extends Exception {
static readonly kind: string;
static getFormatInstance(): FormatException;
}
+10
View File
@@ -0,0 +1,10 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class FormatException extends Exception {
static getFormatInstance() {
return new FormatException();
}
}
FormatException.kind = 'FormatException';
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class IllegalArgumentException extends Exception {
static readonly kind: string;
}
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class IllegalArgumentException extends Exception {
}
IllegalArgumentException.kind = 'IllegalArgumentException';
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class IllegalStateException extends Exception {
static readonly kind: string;
}
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class IllegalStateException extends Exception {
}
IllegalStateException.kind = 'IllegalStateException';
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class IndexOutOfBoundsException extends Exception {
static readonly kind: string;
}
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class IndexOutOfBoundsException extends Exception {
}
IndexOutOfBoundsException.kind = 'IndexOutOfBoundsException';
+22
View File
@@ -0,0 +1,22 @@
import LuminanceSource from './LuminanceSource';
/**
* A wrapper implementation of {@link LuminanceSource} which inverts the luminances it returns -- black becomes
* white and vice versa, and each value becomes (255-value).
*
* @author Sean Owen
*/
export default class InvertedLuminanceSource extends LuminanceSource {
private delegate;
constructor(delegate: LuminanceSource);
getRow(y: number, row?: Uint8ClampedArray): Uint8ClampedArray;
getMatrix(): Uint8ClampedArray;
isCropSupported(): boolean;
crop(left: number, top: number, width: number, height: number): LuminanceSource;
isRotateSupported(): boolean;
/**
* @return original delegate {@link LuminanceSource} since invert undoes itself
*/
invert(): LuminanceSource;
rotateCounterClockwise(): LuminanceSource;
rotateCounterClockwise45(): LuminanceSource;
}
+75
View File
@@ -0,0 +1,75 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import LuminanceSource from './LuminanceSource';
/*namespace com.google.zxing {*/
/**
* A wrapper implementation of {@link LuminanceSource} which inverts the luminances it returns -- black becomes
* white and vice versa, and each value becomes (255-value).
*
* @author Sean Owen
*/
export default class InvertedLuminanceSource extends LuminanceSource {
constructor(delegate) {
super(delegate.getWidth(), delegate.getHeight());
this.delegate = delegate;
}
/*@Override*/
getRow(y /*int*/, row) {
const sourceRow = this.delegate.getRow(y, row);
const width = this.getWidth();
for (let i = 0; i < width; i++) {
sourceRow[i] = /*(byte)*/ (255 - (sourceRow[i] & 0xFF));
}
return sourceRow;
}
/*@Override*/
getMatrix() {
const matrix = this.delegate.getMatrix();
const length = this.getWidth() * this.getHeight();
const invertedMatrix = new Uint8ClampedArray(length);
for (let i = 0; i < length; i++) {
invertedMatrix[i] = /*(byte)*/ (255 - (matrix[i] & 0xFF));
}
return invertedMatrix;
}
/*@Override*/
isCropSupported() {
return this.delegate.isCropSupported();
}
/*@Override*/
crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
return new InvertedLuminanceSource(this.delegate.crop(left, top, width, height));
}
/*@Override*/
isRotateSupported() {
return this.delegate.isRotateSupported();
}
/**
* @return original delegate {@link LuminanceSource} since invert undoes itself
*/
/*@Override*/
invert() {
return this.delegate;
}
/*@Override*/
rotateCounterClockwise() {
return new InvertedLuminanceSource(this.delegate.rotateCounterClockwise());
}
/*@Override*/
rotateCounterClockwise45() {
return new InvertedLuminanceSource(this.delegate.rotateCounterClockwise45());
}
}
+84
View File
@@ -0,0 +1,84 @@
/**
* The purpose of this class hierarchy is to abstract different bitmap implementations across
* platforms into a standard interface for requesting greyscale luminance values. The interface
* only provides immutable methods; therefore crop and rotation create copies. This is to ensure
* that one Reader does not modify the original luminance source and leave it in an unknown state
* for other Readers in the chain.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
declare abstract class LuminanceSource {
private width;
private height;
protected constructor(width: number, height: number);
/**
* Fetches one row of luminance data from the underlying platform's bitmap. Values range from
* 0 (black) to 255 (white). Because Java does not have an unsigned byte type, callers will have
* to bitwise and with 0xff for each value. It is preferable for implementations of this method
* to only fetch this row rather than the whole image, since no 2D Readers may be installed and
* getMatrix() may never be called.
*
* @param y The row to fetch, which must be in [0,getHeight())
* @param row An optional preallocated array. If null or too small, it will be ignored.
* Always use the returned object, and ignore the .length of the array.
* @return An array containing the luminance data.
*/
abstract getRow(y: number, row?: Uint8ClampedArray): Uint8ClampedArray;
/**
* Fetches luminance data for the underlying bitmap. Values should be fetched using:
* {@code int luminance = array[y * width + x] & 0xff}
*
* @return A row-major 2D array of luminance values. Do not use result.length as it may be
* larger than width * height bytes on some platforms. Do not modify the contents
* of the result.
*/
abstract getMatrix(): Uint8ClampedArray;
/**
* @return The width of the bitmap.
*/
getWidth(): number;
/**
* @return The height of the bitmap.
*/
getHeight(): number;
/**
* @return Whether this subclass supports cropping.
*/
isCropSupported(): boolean;
/**
* Returns a new object with cropped image data. Implementations may keep a reference to the
* original data rather than a copy. Only callable if isCropSupported() is true.
*
* @param left The left coordinate, which must be in [0,getWidth())
* @param top The top coordinate, which must be in [0,getHeight())
* @param width The width of the rectangle to crop.
* @param height The height of the rectangle to crop.
* @return A cropped version of this object.
*/
crop(left: number, top: number, width: number, height: number): LuminanceSource;
/**
* @return Whether this subclass supports counter-clockwise rotation.
*/
isRotateSupported(): boolean;
/**
* @return a wrapper of this {@code LuminanceSource} which inverts the luminances it returns -- black becomes
* white and vice versa, and each value becomes (255-value).
*/
abstract invert(): LuminanceSource;
/**
* Returns a new object with rotated image data by 90 degrees counterclockwise.
* Only callable if {@link #isRotateSupported()} is true.
*
* @return A rotated version of this object.
*/
rotateCounterClockwise(): LuminanceSource;
/**
* Returns a new object with rotated image data by 45 degrees counterclockwise.
* Only callable if {@link #isRotateSupported()} is true.
*
* @return A rotated version of this object.
*/
rotateCounterClockwise45(): LuminanceSource;
toString(): string;
}
export default LuminanceSource;
+116
View File
@@ -0,0 +1,116 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import StringBuilder from './util/StringBuilder';
import UnsupportedOperationException from './UnsupportedOperationException';
/*namespace com.google.zxing {*/
/**
* The purpose of this class hierarchy is to abstract different bitmap implementations across
* platforms into a standard interface for requesting greyscale luminance values. The interface
* only provides immutable methods; therefore crop and rotation create copies. This is to ensure
* that one Reader does not modify the original luminance source and leave it in an unknown state
* for other Readers in the chain.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
class LuminanceSource {
constructor(width /*int*/, height /*int*/) {
this.width = width;
this.height = height;
}
/**
* @return The width of the bitmap.
*/
getWidth() {
return this.width;
}
/**
* @return The height of the bitmap.
*/
getHeight() {
return this.height;
}
/**
* @return Whether this subclass supports cropping.
*/
isCropSupported() {
return false;
}
/**
* Returns a new object with cropped image data. Implementations may keep a reference to the
* original data rather than a copy. Only callable if isCropSupported() is true.
*
* @param left The left coordinate, which must be in [0,getWidth())
* @param top The top coordinate, which must be in [0,getHeight())
* @param width The width of the rectangle to crop.
* @param height The height of the rectangle to crop.
* @return A cropped version of this object.
*/
crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
throw new UnsupportedOperationException('This luminance source does not support cropping.');
}
/**
* @return Whether this subclass supports counter-clockwise rotation.
*/
isRotateSupported() {
return false;
}
/**
* Returns a new object with rotated image data by 90 degrees counterclockwise.
* Only callable if {@link #isRotateSupported()} is true.
*
* @return A rotated version of this object.
*/
rotateCounterClockwise() {
throw new UnsupportedOperationException('This luminance source does not support rotation by 90 degrees.');
}
/**
* Returns a new object with rotated image data by 45 degrees counterclockwise.
* Only callable if {@link #isRotateSupported()} is true.
*
* @return A rotated version of this object.
*/
rotateCounterClockwise45() {
throw new UnsupportedOperationException('This luminance source does not support rotation by 45 degrees.');
}
/*@Override*/
toString() {
const row = new Uint8ClampedArray(this.width);
let result = new StringBuilder();
for (let y = 0; y < this.height; y++) {
const sourceRow = this.getRow(y, row);
for (let x = 0; x < this.width; x++) {
const luminance = sourceRow[x] & 0xFF;
let c;
if (luminance < 0x40) {
c = '#';
}
else if (luminance < 0x80) {
c = '+';
}
else if (luminance < 0xC0) {
c = '.';
}
else {
c = ' ';
}
result.append(c);
}
result.append('\n');
}
return result.toString();
}
}
export default LuminanceSource;
+59
View File
@@ -0,0 +1,59 @@
import DecodeHintType from './DecodeHintType';
import Reader from './Reader';
import Result from './Result';
import BinaryBitmap from './BinaryBitmap';
/**
* MultiFormatReader is a convenience class and the main entry point into the library for most uses.
* By default it attempts to decode all barcode formats that the library supports. Optionally, you
* can provide a hints object to request different behavior, for example only decoding QR codes.
*
* @author Sean Owen
* @author dswitkin@google.com (Daniel Switkin)
*/
export default class MultiFormatReader implements Reader {
private hints;
private readers;
/**
* This version of decode honors the intent of Reader.decode(BinaryBitmap) in that it
* passes null as a hint to the decoders. However, that makes it inefficient to call repeatedly.
* Use setHints() followed by decodeWithState() for continuous scan applications.
*
* @param image The pixel data to decode
* @return The contents of the image
*
* @throws NotFoundException Any errors which occurred
*/
/**
* Decode an image using the hints provided. Does not honor existing state.
*
* @param image The pixel data to decode
* @param hints The hints to use, clearing the previous state.
* @return The contents of the image
*
* @throws NotFoundException Any errors which occurred
*/
decode(image: BinaryBitmap, hints?: Map<DecodeHintType, any>): Result;
/**
* Decode an image using the state set up by calling setHints() previously. Continuous scan
* clients will get a <b>large</b> speed increase by using this instead of decode().
*
* @param image The pixel data to decode
* @return The contents of the image
*
* @throws NotFoundException Any errors which occurred
*/
decodeWithState(image: BinaryBitmap): Result;
/**
* This method adds state to the MultiFormatReader. By setting the hints once, subsequent calls
* to decodeWithState(image) can reuse the same set of readers without reallocating memory. This
* is important for performance in continuous scan clients.
*
* @param hints The set of hints to use for subsequent calls to decode(image)
*/
setHints(hints?: Map<DecodeHintType, any> | null): void;
reset(): void;
/**
* @throws NotFoundException
*/
private decodeInternal;
}
+174
View File
@@ -0,0 +1,174 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import DecodeHintType from './DecodeHintType';
import BarcodeFormat from './BarcodeFormat';
import QRCodeReader from './qrcode/QRCodeReader';
import AztecReader from './aztec/AztecReader';
import MultiFormatOneDReader from './oned/MultiFormatOneDReader';
import DataMatrixReader from './datamatrix/DataMatrixReader';
import NotFoundException from './NotFoundException';
import PDF417Reader from './pdf417/PDF417Reader';
import ReaderException from './ReaderException';
/*namespace com.google.zxing {*/
/**
* MultiFormatReader is a convenience class and the main entry point into the library for most uses.
* By default it attempts to decode all barcode formats that the library supports. Optionally, you
* can provide a hints object to request different behavior, for example only decoding QR codes.
*
* @author Sean Owen
* @author dswitkin@google.com (Daniel Switkin)
*/
export default class MultiFormatReader {
/**
* This version of decode honors the intent of Reader.decode(BinaryBitmap) in that it
* passes null as a hint to the decoders. However, that makes it inefficient to call repeatedly.
* Use setHints() followed by decodeWithState() for continuous scan applications.
*
* @param image The pixel data to decode
* @return The contents of the image
*
* @throws NotFoundException Any errors which occurred
*/
/*@Override*/
// public decode(image: BinaryBitmap): Result {
// setHints(null)
// return decodeInternal(image)
// }
/**
* Decode an image using the hints provided. Does not honor existing state.
*
* @param image The pixel data to decode
* @param hints The hints to use, clearing the previous state.
* @return The contents of the image
*
* @throws NotFoundException Any errors which occurred
*/
/*@Override*/
decode(image, hints) {
this.setHints(hints);
return this.decodeInternal(image);
}
/**
* Decode an image using the state set up by calling setHints() previously. Continuous scan
* clients will get a <b>large</b> speed increase by using this instead of decode().
*
* @param image The pixel data to decode
* @return The contents of the image
*
* @throws NotFoundException Any errors which occurred
*/
decodeWithState(image) {
// Make sure to set up the default state so we don't crash
if (this.readers === null || this.readers === undefined) {
this.setHints(null);
}
return this.decodeInternal(image);
}
/**
* This method adds state to the MultiFormatReader. By setting the hints once, subsequent calls
* to decodeWithState(image) can reuse the same set of readers without reallocating memory. This
* is important for performance in continuous scan clients.
*
* @param hints The set of hints to use for subsequent calls to decode(image)
*/
setHints(hints) {
this.hints = hints;
const tryHarder = hints !== null && hints !== undefined && undefined !== hints.get(DecodeHintType.TRY_HARDER);
/*@SuppressWarnings("unchecked")*/
const formats = hints === null || hints === undefined ? null : hints.get(DecodeHintType.POSSIBLE_FORMATS);
const readers = new Array();
if (formats !== null && formats !== undefined) {
const addOneDReader = formats.some(f => f === BarcodeFormat.UPC_A ||
f === BarcodeFormat.UPC_E ||
f === BarcodeFormat.EAN_13 ||
f === BarcodeFormat.EAN_8 ||
f === BarcodeFormat.CODABAR ||
f === BarcodeFormat.CODE_39 ||
f === BarcodeFormat.CODE_93 ||
f === BarcodeFormat.CODE_128 ||
f === BarcodeFormat.ITF ||
f === BarcodeFormat.RSS_14 ||
f === BarcodeFormat.RSS_EXPANDED);
// Put 1D readers upfront in "normal" mode
// TYPESCRIPTPORT: TODO: uncomment below as they are ported
if (addOneDReader && !tryHarder) {
readers.push(new MultiFormatOneDReader(hints));
}
if (formats.includes(BarcodeFormat.QR_CODE)) {
readers.push(new QRCodeReader());
}
if (formats.includes(BarcodeFormat.DATA_MATRIX)) {
readers.push(new DataMatrixReader());
}
if (formats.includes(BarcodeFormat.AZTEC)) {
readers.push(new AztecReader());
}
if (formats.includes(BarcodeFormat.PDF_417)) {
readers.push(new PDF417Reader());
}
// if (formats.includes(BarcodeFormat.MAXICODE)) {
// readers.push(new MaxiCodeReader())
// }
// At end in "try harder" mode
if (addOneDReader && tryHarder) {
readers.push(new MultiFormatOneDReader(hints));
}
}
if (readers.length === 0) {
if (!tryHarder) {
readers.push(new MultiFormatOneDReader(hints));
}
readers.push(new QRCodeReader());
readers.push(new DataMatrixReader());
readers.push(new AztecReader());
readers.push(new PDF417Reader());
// readers.push(new MaxiCodeReader())
if (tryHarder) {
readers.push(new MultiFormatOneDReader(hints));
}
}
this.readers = readers; // .toArray(new Reader[readers.size()])
}
/*@Override*/
reset() {
if (this.readers !== null) {
for (const reader of this.readers) {
reader.reset();
}
}
}
/**
* @throws NotFoundException
*/
decodeInternal(image) {
if (this.readers === null) {
throw new ReaderException('No readers where selected, nothing can be read.');
}
for (const reader of this.readers) {
// Trying to decode with ${reader} reader.
try {
return reader.decode(image, this.hints);
}
catch (ex) {
if (ex instanceof ReaderException) {
continue;
}
// Bad Exception.
}
}
throw new NotFoundException('No MultiFormat Readers were able to detect the code.');
}
}
+13
View File
@@ -0,0 +1,13 @@
import BitMatrix from './common/BitMatrix';
import Writer from './Writer';
import BarcodeFormat from './BarcodeFormat';
import EncodeHintType from './EncodeHintType';
/**
* This is a factory class which finds the appropriate Writer subclass for the BarcodeFormat
* requested and encodes the barcode with the supplied contents.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
export default class MultiFormatWriter implements Writer {
encode(contents: string, format: BarcodeFormat, width: number, height: number, hints: Map<EncodeHintType, any>): BitMatrix;
}
+93
View File
@@ -0,0 +1,93 @@
/*
* Copyright 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// import DataMatrixWriter from './datamatrix/DataMatrixWriter'
// import CodaBarWriter from './oned/CodaBarWriter'
// import Code128Writer from './oned/Code128Writer'
// import Code39Writer from './oned/Code39Writer'
// import Code93Writer from './oned/Code93Writer'
// import EAN13Writer from './oned/EAN13Writer'
// import EAN8Writer from './oned/EAN8Writer'
// import ITFWriter from './oned/ITFWriter'
// import UPCAWriter from './oned/UPCAWriter'
// import UPCEWriter from './oned/UPCEWriter'
// import PDF417Writer from './pdf417/PDF417Writer'
import QRCodeWriter from './qrcode/QRCodeWriter';
import BarcodeFormat from './BarcodeFormat';
import IllegalArgumentException from './IllegalArgumentException';
/*import java.util.Map;*/
/**
* This is a factory class which finds the appropriate Writer subclass for the BarcodeFormat
* requested and encodes the barcode with the supplied contents.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
export default class MultiFormatWriter {
/*@Override*/
// public encode(contents: string,
// format: BarcodeFormat,
// width: number /*int*/,
// height: number /*int*/): BitMatrix /*throws WriterException */ {
// return encode(contents, format, width, height, null)
// }
/*@Override*/
encode(contents, format, width /*int*/, height /*int*/, hints) {
let writer;
switch (format) {
// case BarcodeFormat.EAN_8:
// writer = new EAN8Writer()
// break
// case BarcodeFormat.UPC_E:
// writer = new UPCEWriter()
// break
// case BarcodeFormat.EAN_13:
// writer = new EAN13Writer()
// break
// case BarcodeFormat.UPC_A:
// writer = new UPCAWriter()
// break
case BarcodeFormat.QR_CODE:
writer = new QRCodeWriter();
break;
// case BarcodeFormat.CODE_39:
// writer = new Code39Writer()
// break
// case BarcodeFormat.CODE_93:
// writer = new Code93Writer()
// break
// case BarcodeFormat.CODE_128:
// writer = new Code128Writer()
// break
// case BarcodeFormat.ITF:
// writer = new ITFWriter()
// break
// case BarcodeFormat.PDF_417:
// writer = new PDF417Writer()
// break
// case BarcodeFormat.CODABAR:
// writer = new CodaBarWriter()
// break
// case BarcodeFormat.DATA_MATRIX:
// writer = new DataMatrixWriter()
// break
// case BarcodeFormat.AZTEC:
// writer = new AztecWriter()
// break
default:
throw new IllegalArgumentException('No encoder available for format ' + format);
}
return writer.encode(contents, format, width, height, hints);
}
}
+8
View File
@@ -0,0 +1,8 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class NotFoundException extends Exception {
static readonly kind: string;
static getNotFoundInstance(): NotFoundException;
}
+10
View File
@@ -0,0 +1,10 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class NotFoundException extends Exception {
static getNotFoundInstance() {
return new NotFoundException();
}
}
NotFoundException.kind = 'NotFoundException';
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class NullPointerException extends Exception {
static readonly kind: string;
}
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class NullPointerException extends Exception {
}
NullPointerException.kind = 'NullPointerException';
+6
View File
@@ -0,0 +1,6 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class OutOfMemoryError extends Exception {
}
+6
View File
@@ -0,0 +1,6 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class OutOfMemoryError extends Exception {
}
+35
View File
@@ -0,0 +1,35 @@
import LuminanceSource from './LuminanceSource';
/**
* This object extends LuminanceSource around an array of YUV data returned from the camera driver,
* with the option to crop to a rectangle within the full data. This can be used to exclude
* superfluous pixels around the perimeter and speed up decoding.
*
* It works for any pixel format where the Y channel is planar and appears first, including
* YCbCr_420_SP and YCbCr_422_SP.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
export default class PlanarYUVLuminanceSource extends LuminanceSource {
private yuvData;
private dataWidth;
private dataHeight;
private left;
private top;
private static THUMBNAIL_SCALE_FACTOR;
constructor(yuvData: Uint8ClampedArray, dataWidth: number, dataHeight: number, left: number, top: number, width: number, height: number, reverseHorizontal: boolean);
getRow(y: number, row?: Uint8ClampedArray): Uint8ClampedArray;
getMatrix(): Uint8ClampedArray;
isCropSupported(): boolean;
crop(left: number, top: number, width: number, height: number): LuminanceSource;
renderThumbnail(): Int32Array;
/**
* @return width of image from {@link #renderThumbnail()}
*/
getThumbnailWidth(): number;
/**
* @return height of image from {@link #renderThumbnail()}
*/
getThumbnailHeight(): number;
private reverseHorizontal;
invert(): LuminanceSource;
}
+135
View File
@@ -0,0 +1,135 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*namespace com.google.zxing {*/
import System from './util/System';
import LuminanceSource from './LuminanceSource';
import InvertedLuminanceSource from './InvertedLuminanceSource';
import IllegalArgumentException from './IllegalArgumentException';
/**
* This object extends LuminanceSource around an array of YUV data returned from the camera driver,
* with the option to crop to a rectangle within the full data. This can be used to exclude
* superfluous pixels around the perimeter and speed up decoding.
*
* It works for any pixel format where the Y channel is planar and appears first, including
* YCbCr_420_SP and YCbCr_422_SP.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
export default class PlanarYUVLuminanceSource extends LuminanceSource {
constructor(yuvData, dataWidth /*int*/, dataHeight /*int*/, left /*int*/, top /*int*/, width /*int*/, height /*int*/, reverseHorizontal) {
super(width, height);
this.yuvData = yuvData;
this.dataWidth = dataWidth;
this.dataHeight = dataHeight;
this.left = left;
this.top = top;
if (left + width > dataWidth || top + height > dataHeight) {
throw new IllegalArgumentException('Crop rectangle does not fit within image data.');
}
if (reverseHorizontal) {
this.reverseHorizontal(width, height);
}
}
/*@Override*/
getRow(y /*int*/, row) {
if (y < 0 || y >= this.getHeight()) {
throw new IllegalArgumentException('Requested row is outside the image: ' + y);
}
const width = this.getWidth();
if (row === null || row === undefined || row.length < width) {
row = new Uint8ClampedArray(width);
}
const offset = (y + this.top) * this.dataWidth + this.left;
System.arraycopy(this.yuvData, offset, row, 0, width);
return row;
}
/*@Override*/
getMatrix() {
const width = this.getWidth();
const height = this.getHeight();
// If the caller asks for the entire underlying image, save the copy and give them the
// original data. The docs specifically warn that result.length must be ignored.
if (width === this.dataWidth && height === this.dataHeight) {
return this.yuvData;
}
const area = width * height;
const matrix = new Uint8ClampedArray(area);
let inputOffset = this.top * this.dataWidth + this.left;
// If the width matches the full width of the underlying data, perform a single copy.
if (width === this.dataWidth) {
System.arraycopy(this.yuvData, inputOffset, matrix, 0, area);
return matrix;
}
// Otherwise copy one cropped row at a time.
for (let y = 0; y < height; y++) {
const outputOffset = y * width;
System.arraycopy(this.yuvData, inputOffset, matrix, outputOffset, width);
inputOffset += this.dataWidth;
}
return matrix;
}
/*@Override*/
isCropSupported() {
return true;
}
/*@Override*/
crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
return new PlanarYUVLuminanceSource(this.yuvData, this.dataWidth, this.dataHeight, this.left + left, this.top + top, width, height, false);
}
renderThumbnail() {
const width = this.getWidth() / PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR;
const height = this.getHeight() / PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR;
const pixels = new Int32Array(width * height);
const yuv = this.yuvData;
let inputOffset = this.top * this.dataWidth + this.left;
for (let y = 0; y < height; y++) {
const outputOffset = y * width;
for (let x = 0; x < width; x++) {
const grey = yuv[inputOffset + x * PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR] & 0xff;
pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101);
}
inputOffset += this.dataWidth * PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR;
}
return pixels;
}
/**
* @return width of image from {@link #renderThumbnail()}
*/
getThumbnailWidth() {
return this.getWidth() / PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR;
}
/**
* @return height of image from {@link #renderThumbnail()}
*/
getThumbnailHeight() {
return this.getHeight() / PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR;
}
reverseHorizontal(width /*int*/, height /*int*/) {
const yuvData = this.yuvData;
for (let y = 0, rowStart = this.top * this.dataWidth + this.left; y < height; y++, rowStart += this.dataWidth) {
const middle = rowStart + width / 2;
for (let x1 = rowStart, x2 = rowStart + width - 1; x1 < middle; x1++, x2--) {
const temp = yuvData[x1];
yuvData[x1] = yuvData[x2];
yuvData[x2] = temp;
}
}
}
invert() {
return new InvertedLuminanceSource(this);
}
}
PlanarYUVLuminanceSource.THUMBNAIL_SCALE_FACTOR = 2;
+22
View File
@@ -0,0 +1,22 @@
import './InvertedLuminanceSource';
import LuminanceSource from './LuminanceSource';
/**
* This class is used to help decode images from files which arrive as RGB data from
* an ARGB pixel array. It does not support rotation.
*
* @author dswitkin@google.com (Daniel Switkin)
* @author Betaminos
*/
export default class RGBLuminanceSource extends LuminanceSource {
private dataWidth?;
private dataHeight?;
private left?;
private top?;
private luminances;
constructor(luminances: Uint8ClampedArray | Int32Array, width: number, height: number, dataWidth?: number, dataHeight?: number, left?: number, top?: number);
getRow(y: number, row?: Uint8ClampedArray): Uint8ClampedArray;
getMatrix(): Uint8ClampedArray;
isCropSupported(): boolean;
crop(left: number, top: number, width: number, height: number): LuminanceSource;
invert(): LuminanceSource;
}
+117
View File
@@ -0,0 +1,117 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*namespace com.google.zxing {*/
import './InvertedLuminanceSource'; // required because of circular dependencies between LuminanceSource and InvertedLuminanceSource
import InvertedLuminanceSource from './InvertedLuminanceSource';
import LuminanceSource from './LuminanceSource';
import System from './util/System';
import IllegalArgumentException from './IllegalArgumentException';
/**
* This class is used to help decode images from files which arrive as RGB data from
* an ARGB pixel array. It does not support rotation.
*
* @author dswitkin@google.com (Daniel Switkin)
* @author Betaminos
*/
export default class RGBLuminanceSource extends LuminanceSource {
constructor(luminances, width /*int*/, height /*int*/, dataWidth /*int*/, dataHeight /*int*/, left /*int*/, top /*int*/) {
super(width, height);
this.dataWidth = dataWidth;
this.dataHeight = dataHeight;
this.left = left;
this.top = top;
if (luminances.BYTES_PER_ELEMENT === 4) { // Int32Array
const size = width * height;
const luminancesUint8Array = new Uint8ClampedArray(size);
for (let offset = 0; offset < size; offset++) {
const pixel = luminances[offset];
const r = (pixel >> 16) & 0xff; // red
const g2 = (pixel >> 7) & 0x1fe; // 2 * green
const b = pixel & 0xff; // blue
// Calculate green-favouring average cheaply
luminancesUint8Array[offset] = /*(byte) */ ((r + g2 + b) / 4) & 0xFF;
}
this.luminances = luminancesUint8Array;
}
else {
this.luminances = luminances;
}
if (undefined === dataWidth) {
this.dataWidth = width;
}
if (undefined === dataHeight) {
this.dataHeight = height;
}
if (undefined === left) {
this.left = 0;
}
if (undefined === top) {
this.top = 0;
}
if (this.left + width > this.dataWidth || this.top + height > this.dataHeight) {
throw new IllegalArgumentException('Crop rectangle does not fit within image data.');
}
}
/*@Override*/
getRow(y /*int*/, row) {
if (y < 0 || y >= this.getHeight()) {
throw new IllegalArgumentException('Requested row is outside the image: ' + y);
}
const width = this.getWidth();
if (row === null || row === undefined || row.length < width) {
row = new Uint8ClampedArray(width);
}
const offset = (y + this.top) * this.dataWidth + this.left;
System.arraycopy(this.luminances, offset, row, 0, width);
return row;
}
/*@Override*/
getMatrix() {
const width = this.getWidth();
const height = this.getHeight();
// If the caller asks for the entire underlying image, save the copy and give them the
// original data. The docs specifically warn that result.length must be ignored.
if (width === this.dataWidth && height === this.dataHeight) {
return this.luminances;
}
const area = width * height;
const matrix = new Uint8ClampedArray(area);
let inputOffset = this.top * this.dataWidth + this.left;
// If the width matches the full width of the underlying data, perform a single copy.
if (width === this.dataWidth) {
System.arraycopy(this.luminances, inputOffset, matrix, 0, area);
return matrix;
}
// Otherwise copy one cropped row at a time.
for (let y = 0; y < height; y++) {
const outputOffset = y * width;
System.arraycopy(this.luminances, inputOffset, matrix, outputOffset, width);
inputOffset += this.dataWidth;
}
return matrix;
}
/*@Override*/
isCropSupported() {
return true;
}
/*@Override*/
crop(left /*int*/, top /*int*/, width /*int*/, height /*int*/) {
return new RGBLuminanceSource(this.luminances, width, height, this.dataWidth, this.dataHeight, this.left + left, this.top + top);
}
invert() {
return new InvertedLuminanceSource(this);
}
}
+49
View File
@@ -0,0 +1,49 @@
import BinaryBitmap from './BinaryBitmap';
import Result from './Result';
import DecodeHintType from './DecodeHintType';
export default Reader;
/**
* Implementations of this interface can decode an image of a barcode in some format into
* the it: string encodes. For example, {@link com.google.zxing.qrcode.QRCodeReader} can
* decode a QR code. The decoder may optionally receive hints from the caller which may help
* it decode more quickly or accurately.
*
* See {@link MultiFormatReader}, which attempts to determine what barcode
* format is present within the image as well, and then decodes it accordingly.
*
* @author Sean Owen
* @author dswitkin@google.com (Daniel Switkin)
*/
interface Reader {
/**
* Locates and decodes a barcode in some format within an image.
*
* @param image image of barcode to decode
* @return which: string the barcode encodes
* @throws NotFoundException if no potential barcode is found
* @throws ChecksumException if a potential barcode is found but does not pass its checksum
* @throws FormatException if a potential barcode is found but format is invalid
*/
/**
* Locates and decodes a barcode in some format within an image. This method also accepts
* hints, each possibly associated to some data, which may help the implementation decode.
*
* @param image image of barcode to decode
* @param hints passed as a {@link Map} from {@link DecodeHintType}
* to arbitrary data. The
* meaning of the data depends upon the hint type. The implementation may or may not do
* anything with these hints.
*
* @return which: string the barcode encodes
*
* @throws NotFoundException if no potential barcode is found
* @throws ChecksumException if a potential barcode is found but does not pass its checksum
* @throws FormatException if a potential barcode is found but format is invalid
*/
decode(image: BinaryBitmap, hints?: Map<DecodeHintType, any> | null): Result;
/**
* Resets any internal state the implementation has after a decode, to prepare it
* for reuse.
*/
reset(): void;
}
+15
View File
@@ -0,0 +1,15 @@
/*
* Copyright 2007 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class ReaderException extends Exception {
static readonly kind: string;
}
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class ReaderException extends Exception {
}
ReaderException.kind = 'ReaderException';
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class ReedSolomonException extends Exception {
static readonly kind: string;
}
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class ReedSolomonException extends Exception {
}
ReedSolomonException.kind = 'ReedSolomonException';
+52
View File
@@ -0,0 +1,52 @@
import ResultPoint from './ResultPoint';
import BarcodeFormat from './BarcodeFormat';
import ResultMetadataType from './ResultMetadataType';
/**
* <p>Encapsulates the result of decoding a barcode within an image.</p>
*
* @author Sean Owen
*/
export default class Result {
private text;
private rawBytes;
private numBits;
private resultPoints;
private format;
private timestamp;
private resultMetadata;
constructor(text: string, rawBytes: Uint8Array, numBits: number, resultPoints: ResultPoint[], format: BarcodeFormat, timestamp?: number);
/**
* @return raw text encoded by the barcode
*/
getText(): string;
/**
* @return raw bytes encoded by the barcode, if applicable, otherwise {@code null}
*/
getRawBytes(): Uint8Array;
/**
* @return how many bits of {@link #getRawBytes()} are valid; typically 8 times its length
* @since 3.3.0
*/
getNumBits(): number;
/**
* @return points related to the barcode in the image. These are typically points
* identifying finder patterns or the corners of the barcode. The exact meaning is
* specific to the type of barcode that was decoded.
*/
getResultPoints(): Array<ResultPoint>;
/**
* @return {@link BarcodeFormat} representing the format of the barcode that was decoded
*/
getBarcodeFormat(): BarcodeFormat;
/**
* @return {@link Map} mapping {@link ResultMetadataType} keys to values. May be
* {@code null}. This contains optional metadata about what was detected about the barcode,
* like orientation.
*/
getResultMetadata(): Map<ResultMetadataType, Object>;
putMetadata(type: ResultMetadataType, value: Object): void;
putAllMetadata(metadata: Map<ResultMetadataType, Object>): void;
addResultPoints(newPoints: Array<ResultPoint>): void;
getTimestamp(): number;
toString(): string;
}
+138
View File
@@ -0,0 +1,138 @@
/*
* Copyright 2007 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import System from './util/System';
/**
* <p>Encapsulates the result of decoding a barcode within an image.</p>
*
* @author Sean Owen
*/
export default class Result {
// public constructor(private text: string,
// Uint8Array rawBytes,
// ResultPoconst resultPoints: Int32Array,
// BarcodeFormat format) {
// this(text, rawBytes, resultPoints, format, System.currentTimeMillis())
// }
// public constructor(text: string,
// Uint8Array rawBytes,
// ResultPoconst resultPoints: Int32Array,
// BarcodeFormat format,
// long timestamp) {
// this(text, rawBytes, rawBytes == null ? 0 : 8 * rawBytes.length,
// resultPoints, format, timestamp)
// }
constructor(text, rawBytes, numBits = rawBytes == null ? 0 : 8 * rawBytes.length, resultPoints, format, timestamp = System.currentTimeMillis()) {
this.text = text;
this.rawBytes = rawBytes;
this.numBits = numBits;
this.resultPoints = resultPoints;
this.format = format;
this.timestamp = timestamp;
this.text = text;
this.rawBytes = rawBytes;
if (undefined === numBits || null === numBits) {
this.numBits = (rawBytes === null || rawBytes === undefined) ? 0 : 8 * rawBytes.length;
}
else {
this.numBits = numBits;
}
this.resultPoints = resultPoints;
this.format = format;
this.resultMetadata = null;
if (undefined === timestamp || null === timestamp) {
this.timestamp = System.currentTimeMillis();
}
else {
this.timestamp = timestamp;
}
}
/**
* @return raw text encoded by the barcode
*/
getText() {
return this.text;
}
/**
* @return raw bytes encoded by the barcode, if applicable, otherwise {@code null}
*/
getRawBytes() {
return this.rawBytes;
}
/**
* @return how many bits of {@link #getRawBytes()} are valid; typically 8 times its length
* @since 3.3.0
*/
getNumBits() {
return this.numBits;
}
/**
* @return points related to the barcode in the image. These are typically points
* identifying finder patterns or the corners of the barcode. The exact meaning is
* specific to the type of barcode that was decoded.
*/
getResultPoints() {
return this.resultPoints;
}
/**
* @return {@link BarcodeFormat} representing the format of the barcode that was decoded
*/
getBarcodeFormat() {
return this.format;
}
/**
* @return {@link Map} mapping {@link ResultMetadataType} keys to values. May be
* {@code null}. This contains optional metadata about what was detected about the barcode,
* like orientation.
*/
getResultMetadata() {
return this.resultMetadata;
}
putMetadata(type, value) {
if (this.resultMetadata === null) {
this.resultMetadata = new Map();
}
this.resultMetadata.set(type, value);
}
putAllMetadata(metadata) {
if (metadata !== null) {
if (this.resultMetadata === null) {
this.resultMetadata = metadata;
}
else {
this.resultMetadata = new Map(metadata);
}
}
}
addResultPoints(newPoints) {
const oldPoints = this.resultPoints;
if (oldPoints === null) {
this.resultPoints = newPoints;
}
else if (newPoints !== null && newPoints.length > 0) {
const allPoints = new Array(oldPoints.length + newPoints.length);
System.arraycopy(oldPoints, 0, allPoints, 0, oldPoints.length);
System.arraycopy(newPoints, 0, allPoints, oldPoints.length, newPoints.length);
this.resultPoints = allPoints;
}
}
getTimestamp() {
return this.timestamp;
}
/*@Override*/
toString() {
return this.text;
}
}
+68
View File
@@ -0,0 +1,68 @@
/**
* Represents some type of metadata about the result of the decoding that the decoder
* wishes to communicate back to the caller.
*
* @author Sean Owen
*/
declare enum ResultMetadataType {
/**
* Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.
*/
OTHER = 0,
/**
* Denotes the likely approximate orientation of the barcode in the image. This value
* is given as degrees rotated clockwise from the normal, upright orientation.
* For example a 1D barcode which was found by reading top-to-bottom would be
* said to have orientation "90". This key maps to an {@link Integer} whose
* value is in the range [0,360).
*/
ORIENTATION = 1,
/**
* <p>2D barcode formats typically encode text, but allow for a sort of 'byte mode'
* which is sometimes used to encode binary data. While {@link Result} makes available
* the complete raw bytes in the barcode for these formats, it does not offer the bytes
* from the byte segments alone.</p>
*
* <p>This maps to a {@link java.util.List} of byte arrays corresponding to the
* raw bytes in the byte segments in the barcode, in order.</p>
*/
BYTE_SEGMENTS = 2,
/**
* Error correction level used, if applicable. The value type depends on the
* format, but is typically a String.
*/
ERROR_CORRECTION_LEVEL = 3,
/**
* For some periodicals, indicates the issue number as an {@link Integer}.
*/
ISSUE_NUMBER = 4,
/**
* For some products, indicates the suggested retail price in the barcode as a
* formatted {@link String}.
*/
SUGGESTED_PRICE = 5,
/**
* For some products, the possible country of manufacture as a {@link String} denoting the
* ISO country code. Some map to multiple possible countries, like "US/CA".
*/
POSSIBLE_COUNTRY = 6,
/**
* For some products, the extension text
*/
UPC_EAN_EXTENSION = 7,
/**
* PDF417-specific metadata
*/
PDF417_EXTRA_METADATA = 8,
/**
* If the code format supports structured append and the current scanned code is part of one then the
* sequence number is given with it.
*/
STRUCTURED_APPEND_SEQUENCE = 9,
/**
* If the code format supports structured append and the current scanned code is part of one then the
* parity is given with it.
*/
STRUCTURED_APPEND_PARITY = 10
}
export default ResultMetadataType;
+85
View File
@@ -0,0 +1,85 @@
/*
* Copyright 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*namespace com.google.zxing {*/
/**
* Represents some type of metadata about the result of the decoding that the decoder
* wishes to communicate back to the caller.
*
* @author Sean Owen
*/
var ResultMetadataType;
(function (ResultMetadataType) {
/**
* Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.
*/
ResultMetadataType[ResultMetadataType["OTHER"] = 0] = "OTHER";
/**
* Denotes the likely approximate orientation of the barcode in the image. This value
* is given as degrees rotated clockwise from the normal, upright orientation.
* For example a 1D barcode which was found by reading top-to-bottom would be
* said to have orientation "90". This key maps to an {@link Integer} whose
* value is in the range [0,360).
*/
ResultMetadataType[ResultMetadataType["ORIENTATION"] = 1] = "ORIENTATION";
/**
* <p>2D barcode formats typically encode text, but allow for a sort of 'byte mode'
* which is sometimes used to encode binary data. While {@link Result} makes available
* the complete raw bytes in the barcode for these formats, it does not offer the bytes
* from the byte segments alone.</p>
*
* <p>This maps to a {@link java.util.List} of byte arrays corresponding to the
* raw bytes in the byte segments in the barcode, in order.</p>
*/
ResultMetadataType[ResultMetadataType["BYTE_SEGMENTS"] = 2] = "BYTE_SEGMENTS";
/**
* Error correction level used, if applicable. The value type depends on the
* format, but is typically a String.
*/
ResultMetadataType[ResultMetadataType["ERROR_CORRECTION_LEVEL"] = 3] = "ERROR_CORRECTION_LEVEL";
/**
* For some periodicals, indicates the issue number as an {@link Integer}.
*/
ResultMetadataType[ResultMetadataType["ISSUE_NUMBER"] = 4] = "ISSUE_NUMBER";
/**
* For some products, indicates the suggested retail price in the barcode as a
* formatted {@link String}.
*/
ResultMetadataType[ResultMetadataType["SUGGESTED_PRICE"] = 5] = "SUGGESTED_PRICE";
/**
* For some products, the possible country of manufacture as a {@link String} denoting the
* ISO country code. Some map to multiple possible countries, like "US/CA".
*/
ResultMetadataType[ResultMetadataType["POSSIBLE_COUNTRY"] = 6] = "POSSIBLE_COUNTRY";
/**
* For some products, the extension text
*/
ResultMetadataType[ResultMetadataType["UPC_EAN_EXTENSION"] = 7] = "UPC_EAN_EXTENSION";
/**
* PDF417-specific metadata
*/
ResultMetadataType[ResultMetadataType["PDF417_EXTRA_METADATA"] = 8] = "PDF417_EXTRA_METADATA";
/**
* If the code format supports structured append and the current scanned code is part of one then the
* sequence number is given with it.
*/
ResultMetadataType[ResultMetadataType["STRUCTURED_APPEND_SEQUENCE"] = 9] = "STRUCTURED_APPEND_SEQUENCE";
/**
* If the code format supports structured append and the current scanned code is part of one then the
* parity is given with it.
*/
ResultMetadataType[ResultMetadataType["STRUCTURED_APPEND_PARITY"] = 10] = "STRUCTURED_APPEND_PARITY";
})(ResultMetadataType || (ResultMetadataType = {}));
export default ResultMetadataType;
+34
View File
@@ -0,0 +1,34 @@
import { float, int } from '../customTypings';
/**
* <p>Encapsulates a point of interest in an image containing a barcode. Typically, this
* would be the location of a finder pattern or the corner of the barcode, for example.</p>
*
* @author Sean Owen
*/
export default class ResultPoint {
private x;
private y;
constructor(x: float, y: float);
getX(): float;
getY(): float;
equals(other: Object): boolean;
hashCode(): int;
toString(): string;
/**
* Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC
* and BC is less than AC, and the angle between BC and BA is less than 180 degrees.
*
* @param patterns array of three {@code ResultPoint} to order
*/
static orderBestPatterns(patterns: Array<ResultPoint>): void;
/**
* @param pattern1 first pattern
* @param pattern2 second pattern
* @return distance between two points
*/
static distance(pattern1: ResultPoint, pattern2: ResultPoint): float;
/**
* Returns the z component of the cross product between vectors BC and BA.
*/
private static crossProductZ;
}
+111
View File
@@ -0,0 +1,111 @@
/*
* Copyright 2007 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*namespace com.google.zxing {*/
import MathUtils from './common/detector/MathUtils';
import Float from './util/Float';
/**
* <p>Encapsulates a point of interest in an image containing a barcode. Typically, this
* would be the location of a finder pattern or the corner of the barcode, for example.</p>
*
* @author Sean Owen
*/
export default class ResultPoint {
constructor(x, y) {
this.x = x;
this.y = y;
}
getX() {
return this.x;
}
getY() {
return this.y;
}
/*@Override*/
equals(other) {
if (other instanceof ResultPoint) {
const otherPoint = other;
return this.x === otherPoint.x && this.y === otherPoint.y;
}
return false;
}
/*@Override*/
hashCode() {
return 31 * Float.floatToIntBits(this.x) + Float.floatToIntBits(this.y);
}
/*@Override*/
toString() {
return '(' + this.x + ',' + this.y + ')';
}
/**
* Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC
* and BC is less than AC, and the angle between BC and BA is less than 180 degrees.
*
* @param patterns array of three {@code ResultPoint} to order
*/
static orderBestPatterns(patterns) {
// Find distances between pattern centers
const zeroOneDistance = this.distance(patterns[0], patterns[1]);
const oneTwoDistance = this.distance(patterns[1], patterns[2]);
const zeroTwoDistance = this.distance(patterns[0], patterns[2]);
let pointA;
let pointB;
let pointC;
// Assume one closest to other two is B; A and C will just be guesses at first
if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
pointB = patterns[0];
pointA = patterns[1];
pointC = patterns[2];
}
else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
pointB = patterns[1];
pointA = patterns[0];
pointC = patterns[2];
}
else {
pointB = patterns[2];
pointA = patterns[0];
pointC = patterns[1];
}
// Use cross product to figure out whether A and C are correct or flipped.
// This asks whether BC x BA has a positive z component, which is the arrangement
// we want for A, B, C. If it's negative, then we've got it flipped around and
// should swap A and C.
if (this.crossProductZ(pointA, pointB, pointC) < 0.0) {
const temp = pointA;
pointA = pointC;
pointC = temp;
}
patterns[0] = pointA;
patterns[1] = pointB;
patterns[2] = pointC;
}
/**
* @param pattern1 first pattern
* @param pattern2 second pattern
* @return distance between two points
*/
static distance(pattern1, pattern2) {
return MathUtils.distance(pattern1.x, pattern1.y, pattern2.x, pattern2.y);
}
/**
* Returns the z component of the cross product between vectors BC and BA.
*/
static crossProductZ(pointA, pointB, pointC) {
const bX = pointB.x;
const bY = pointB.y;
return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));
}
}
+11
View File
@@ -0,0 +1,11 @@
import ResultPoint from './ResultPoint';
export default ResultPointCallback;
/**
* Callback which is invoked when a possible result point (significant
* point in the barcode image such as a corner) is found.
*
* @see DecodeHintType#NEED_RESULT_POINT_CALLBACK
*/
interface ResultPointCallback {
foundPossibleResultPoint(point: ResultPoint): void;
}
+15
View File
@@ -0,0 +1,15 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class UnsupportedOperationException extends Exception {
static readonly kind: string;
}
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class UnsupportedOperationException extends Exception {
}
UnsupportedOperationException.kind = 'UnsupportedOperationException';
+31
View File
@@ -0,0 +1,31 @@
import BitMatrix from './common/BitMatrix';
import BarcodeFormat from './BarcodeFormat';
import EncodeHintType from './EncodeHintType';
export default Writer;
/**
* The base class for all objects which encode/generate a barcode image.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
interface Writer {
/**
* Encode a barcode using the default settings.
*
* @param contents The contents to encode in the barcode
* @param format The barcode format to generate
* @param width The preferred width in pixels
* @param height The preferred height in pixels
* @return {@link BitMatrix} representing encoded barcode image
* @throws WriterException if contents cannot be encoded legally in a format
*/
/**
* @param contents The contents to encode in the barcode
* @param format The barcode format to generate
* @param width The preferred width in pixels
* @param height The preferred height in pixels
* @param hints Additional parameters to supply to the encoder
* @return {@link BitMatrix} representing encoded barcode image
* @throws WriterException if contents cannot be encoded legally in a format
*/
encode(contents: string, format: BarcodeFormat, width: number, height: number, hints: Map<EncodeHintType, any>): BitMatrix;
}
+15
View File
@@ -0,0 +1,15 @@
/*
* Copyright 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class WriterException extends Exception {
static readonly kind: string;
}
+7
View File
@@ -0,0 +1,7 @@
import Exception from './Exception';
/**
* Custom Error class of type Exception.
*/
export default class WriterException extends Exception {
}
WriterException.kind = 'WriterException';
+18
View File
@@ -0,0 +1,18 @@
import ResultPoint from '../ResultPoint';
import BitMatrix from '../common/BitMatrix';
import DetectorResult from '../common/DetectorResult';
/**
* <p>Extends {@link DetectorResult} with more information specific to the Aztec format,
* like the number of layers and whether it's compact.</p>
*
* @author Sean Owen
*/
export default class AztecDetectorResult extends DetectorResult {
private compact;
private nbDatablocks;
private nbLayers;
constructor(bits: BitMatrix, points: ResultPoint[], compact: boolean, nbDatablocks: number, nbLayers: number);
getNbLayers(): number;
getNbDatablocks(): number;
isCompact(): boolean;
}
+39
View File
@@ -0,0 +1,39 @@
/*
* Copyright 2010 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import DetectorResult from '../common/DetectorResult';
/**
* <p>Extends {@link DetectorResult} with more information specific to the Aztec format,
* like the number of layers and whether it's compact.</p>
*
* @author Sean Owen
*/
export default class AztecDetectorResult extends DetectorResult {
constructor(bits, points, compact, nbDatablocks, nbLayers) {
super(bits, points);
this.compact = compact;
this.nbDatablocks = nbDatablocks;
this.nbLayers = nbLayers;
}
getNbLayers() {
return this.nbLayers;
}
getNbDatablocks() {
return this.nbDatablocks;
}
isCompact() {
return this.compact;
}
}
+21
View File
@@ -0,0 +1,21 @@
import Reader from '../Reader';
import Result from '../Result';
import BinaryBitmap from '../BinaryBitmap';
import DecodeHintType from '../DecodeHintType';
/**
* This implementation can detect and decode Aztec codes in an image.
*
* @author David Olivier
*/
export default class AztecReader implements Reader {
/**
* Locates and decodes a Data Matrix code in an image.
*
* @return a String representing the content encoded by the Data Matrix code
* @throws NotFoundException if a Data Matrix code cannot be found
* @throws FormatException if a Data Matrix code cannot be decoded
*/
decode(image: BinaryBitmap, hints?: Map<DecodeHintType, any> | null): Result;
private reportFoundResultPoints;
reset(): void;
}
+91
View File
@@ -0,0 +1,91 @@
/*
* Copyright 2010 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Result from '../Result';
import BarcodeFormat from '../BarcodeFormat';
import DecodeHintType from '../DecodeHintType';
import ResultMetadataType from '../ResultMetadataType';
import System from '../util/System';
import Decoder from './decoder/Decoder';
import Detector from './detector/Detector';
// import java.util.List;
// import java.util.Map;
/**
* This implementation can detect and decode Aztec codes in an image.
*
* @author David Olivier
*/
export default class AztecReader {
/**
* Locates and decodes a Data Matrix code in an image.
*
* @return a String representing the content encoded by the Data Matrix code
* @throws NotFoundException if a Data Matrix code cannot be found
* @throws FormatException if a Data Matrix code cannot be decoded
*/
decode(image, hints = null) {
let exception = null;
let detector = new Detector(image.getBlackMatrix());
let points = null;
let decoderResult = null;
try {
let detectorResult = detector.detectMirror(false);
points = detectorResult.getPoints();
this.reportFoundResultPoints(hints, points);
decoderResult = new Decoder().decode(detectorResult);
}
catch (e) {
exception = e;
}
if (decoderResult == null) {
try {
let detectorResult = detector.detectMirror(true);
points = detectorResult.getPoints();
this.reportFoundResultPoints(hints, points);
decoderResult = new Decoder().decode(detectorResult);
}
catch (e) {
if (exception != null) {
throw exception;
}
throw e;
}
}
let result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), decoderResult.getNumBits(), points, BarcodeFormat.AZTEC, System.currentTimeMillis());
let byteSegments = decoderResult.getByteSegments();
if (byteSegments != null) {
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
}
let ecLevel = decoderResult.getECLevel();
if (ecLevel != null) {
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
}
return result;
}
reportFoundResultPoints(hints, points) {
if (hints != null) {
let rpcb = hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
if (rpcb != null) {
points.forEach((point, idx, arr) => {
rpcb.foundPossibleResultPoint(point);
});
}
}
}
// @Override
reset() {
// do nothing
}
}

Some files were not shown because too many files have changed in this diff Show More