Barcode Scanner using ZXing, ML Kit, and Dynamsoft
Barcode has been around for more than half a century. There are various types of barcodes and reading libraries. Some libraries focus on one barcode format like libdmtx while most libraries can read all kinds of formats. In this article, we are going to implement a mobile barcode scanner with three libraries to make it easy to decide which one to use:
- ZXing: an open-source library
- ML Kit: a free library by Google
- Dynamsoft Barcode Reader: an enterprise-grade SDK by Dynamsoft
Steps on Building a React Native Barcode Scanner
There are many ways to build an app. We can use Java or Kotlin for Android development and Objective-C/Swift for iOS development. Here, we are going to use React Native to create a cross-platform app. Using the libraries is largely the same using different languages.
New Project
Create a new project:
npx @react-native-community/cli@latest init BarcodeScanner
Add Camera Permissions
For Android, add the following to android\app\src\main\AndroidManifest.xml
:
<uses-permission android:name="android.permission.CAMERA" />
For iOS add the following to Info.plist
:
<key>NSCameraUsageDescription</key>
<string>For barcode scanning</string>
Add Dependencies
-
Install
react-native-vision-camera
to open the camera.npm install react-native-vision-camera react-native-worklets-core
-
Install
react-native-image-picker
to pick an image.npm install react-native-image-picker
-
Install the zxing library.
npm install vision-camera-zxing
-
Install the ML Kit library.
npm install react-native-vision-camera-barcodes-scanner
-
Install the Dynamsoft Barcode Reader library.
npm install vision-camera-dynamsoft-barcode-reader
In addition, add the following to babel.conf.js
:
module.exports = {
presets: ['module:@react-native/babel-preset'],
+ plugins: [
+ 'react-native-worklets-core/plugin',
+ ],
};
Read Barcodes from the Camera
-
In a component, use Vision Camera to open the camera.
const BarcodeScanner: React.FC<props> = (props: props) => { const [hasPermission, setHasPermission] = React.useState(false); const [isActive, setIsActive] = React.useState(false); const device = useCameraDevice("back"); const cameraFormat = useCameraFormat(device, [ { videoResolution: { width: 1280, height: 720 } }, { fps: 60 } ]) React.useEffect(() => { (async () => { const status = await Camera.requestCameraPermission(); setHasPermission(status === 'granted'); setIsActive(true); })(); } }, []); return ( <> {device && hasPermission && ( <> <Camera style={StyleSheet.absoluteFill} device={device} isActive={isActive} format={cameraFormat} frameProcessor={frameProcessor} resizeMode='contain' /> </> </> ); }
-
Register a frame processor to read barcodes from the camera frames using the selected barcode reading engine.
import { zxing, type Result } from 'vision-camera-zxing'; import { useBarcodeScanner } from "react-native-vision-camera-barcodes-scanner"; import { decode, TextResult } from 'vision-camera-dynamsoft-barcode-reader'; const {scanBarcodes} = useBarcodeScanner(); const frameProcessor = useFrameProcessor(frame => { 'worklet' runAsync(frame, () => { 'worklet' let results; if (engine.value === "ZXing") { results = zxing(frame,{multiple:true}); }else if (engine.value === "Dynamsoft") { results = decode(frame,{rotateImage:false}); }else{ results = scanBarcodes(frame); } console.log(results); }) }, [])
Read Barcodes from an Album Image
-
Pick an image from the album.
let options: ImageLibraryOptions = { mediaType: 'photo', includeBase64: true, } let response = await launchImageLibrary(options);
-
Read barcodes from the image using its base64 or uri. The results are unified to one interface for representing the barcode.
if (response && response.assets) { if (selectedEngine != "MLKit") { if (response.assets[0]!.base64) { if (selectedEngine === "Dynamsoft") { let textResults = await DBR.decodeBase64(response.assets[0]!.base64); let results = []; for (let index = 0; index < textResults.length; index++) { const tr = textResults[index]; const points:Point[] = []; points.push({x:tr.x1,y:tr.y1}); points.push({x:tr.x2,y:tr.y2}); points.push({x:tr.x3,y:tr.y3}); points.push({x:tr.x4,y:tr.y4}); const result:Result = { barcodeText:tr.barcodeText, barcodeFormat:tr.barcodeFormat, barcodeBytesBase64:tr.barcodeBytesBase64, points:points } results.push(result); } setBarcodeResults(results); }else{ let results = await decodeBase64(response.assets[0]!.base64,{multiple:true}); setBarcodeResults(results); } } }else{ if (response && response.assets[0] && response.assets[0].uri) { const uri = response.assets[0].uri as string; let results = []; const barcodes = await ImageScanner(uri); for (let index = 0; index < barcodes.length; index++) { const barcode = barcodes[index]; const points:Point[] = []; points.push({x:barcode.left,y:barcode.top}); points.push({x:barcode.right,y:barcode.top}); points.push({x:barcode.right,y:barcode.bottom}); points.push({x:barcode.left,y:barcode.bottom}); const result:Result = { barcodeText:barcode.rawValue, barcodeFormat:"", barcodeBytesBase64:"", points:points } results.push(result); } setBarcodeResults(results); } } }
Comparison of the Libraries
After the demo is done, we can compare the libraries.
Barcode Formats
Dynamsoft has the most supported barcode formats.
ZXing | ML Kit | Dynamsoft |
---|---|---|
UPC-A | UPC-A | UPC-A |
UPC-E | UPC-E | UPC-E |
EAN-8 | EAN-8 | EAN-8 |
EAN-13 | EAN-13 | EAN-13 |
Code 39 | Code 39 | Code 39 |
Code 93 | Code 93 | Code 93 |
ITF | ITF | ITF |
Codabar | Codabar | Codabar |
QR Code | QR Code | QR Code |
Aztec | Aztec | Aztec |
Data Matrix | Data Matrix | Data Matrix |
PDF417 | PDF417 | PDF417 |
Maxicode | Maxicode | |
RSS-14 (GS1 DataBar) | RSS-14 (GS1 DataBar) | |
Code 11 | ||
Interleaved 2 of 5 | ||
Industrial 2 of 5 | ||
GS1 Composite Code | ||
DotCode | ||
Pharmacode | ||
Patch Code |
GS1 Composite which only Dynamsoft can read:
Scan Angle
ZXing has to align the barcode with the camera to scan it.
Dynamsoft and ML Kit can read the barcodes in any angle. Dynamsoft can precisely return the coordinates of barcodes.
Dynamsoft:
ML Kit:
Barcode Details
Dynamsoft can return more details about the barcode, like its raw bytes, codewords, orientation, etc.
Images in Bad Conditions
Dynamsoft can handle more image conditions.
Type | Image | ZXing | ML Kit | Dynamsoft |
---|---|---|---|---|
Inverted | × | √ | √ | |
Zero quietzone | × | × | √ | |
Curved | × | × | √ | |
Damaged | × | √ | √ |
Check out the QR code reading benchmark article to view more examples.
Settings
ZXing, ML Kit and Dynamsoft all have the ability to set which barcode formats to use while Dynamsoft has more settings like the following:
- Scan region.
- Expected barcode count.
- Localization methods.
- Binarization methods.
- Timeout.
Check out the docs to learn more.
Enterprise Support
Dynamsoft is an commercial SDK. It has a better support and provides customization services to guarantee the success of your business.
Source Code
Check out the source code of the demo to have a try:
https://github.com/tony-xlh/react-native-zxing-mlkit-dynamsoft