vision-camera-simple-scanner
Version:
High performance barcode scanner for React Native using VisionCamera, forked from vision-camera-barcode-scanner
86 lines (74 loc) • 2.61 kB
text/typescript
import { NativeEventEmitter, NativeModules, Platform } from 'react-native';
import { VisionCameraProxy, type Frame } from 'react-native-vision-camera';
import type {
AndroidBarcode,
Barcode,
BarcodeType,
FrameProcessorPlugin,
VisionCameraConstants,
iOSBarcode,
} from './types';
import { normalizeNativeBarcode } from './utils';
const LINKING_ERROR =
`The package 'vision-camera-code-scanner' doesn't seem to be linked. Make sure: \n\n` +
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
'- You rebuilt the app after installing the package\n' +
'- You are not using Expo Go\n';
export const VisionCameraSimpleScanner = NativeModules.VisionCameraSimpleScanner
? NativeModules.VisionCameraSimpleScanner
: new Proxy(
{},
{
get() {
throw new Error(LINKING_ERROR);
},
},
);
const { MODULE_NAME, BARCODE_TYPES, BARCODE_FORMATS } =
VisionCameraSimpleScanner.getConstants() as VisionCameraConstants;
export { BARCODE_FORMATS, BARCODE_TYPES };
const visionCameraEventEmitter = new NativeEventEmitter(
VisionCameraSimpleScanner,
);
export const onBarcodeDetected = (
callback: (barcode: iOSBarcode | AndroidBarcode) => unknown,
) => {
visionCameraEventEmitter.addListener('onBarcodeDetected', (nativeBarcode) => {
callback(nativeBarcode);
});
};
const visionCameraProcessorPlugin = VisionCameraProxy.initFrameProcessorPlugin(
MODULE_NAME,
) as FrameProcessorPlugin | null;
export type ScanBarcodesOptions = {
barcodeTypes?: BarcodeType[];
regionOfInterest?: [number, number, number, number];
};
export const scanCodes = (
frame: Frame,
options?: ScanBarcodesOptions,
): Barcode[] => {
'worklet';
if (visionCameraProcessorPlugin == null) {
throw new Error(`Failed to load Frame Processor Plugin "${MODULE_NAME}"!`);
}
// console.log(`frame.width=${frame.width}, frame.height=${frame.height}`);
// @ts-expect-error - incrementRefCount() is not exposed in the typings
frame.incrementRefCount && frame.incrementRefCount();
const nativeCodes = visionCameraProcessorPlugin.call(
frame,
options,
) as unknown as (AndroidBarcode | iOSBarcode)[];
// @ts-expect-error - decrementRefCount() is not exposed in the typings
frame.decrementRefCount && frame.decrementRefCount();
if (!Array.isArray(nativeCodes)) {
console.log(
`Native frame processor ${MODULE_NAME} failed to return a proper array!`,
nativeCodes,
);
return [];
}
return nativeCodes
.slice()
.map((nativeBarcode) => normalizeNativeBarcode(nativeBarcode, frame));
};