QR/Barcode Scanning
What is a Code Scanner?
A Code Scanner is a separate Camera output (just like photo or video) that can detect a variety of machine-readable codes, such as:
- QR: Square QR codes
- Aztec: Square Aztec codes
- Data Matrix: Square Data Matrix codes
- Barcode (EAN): EAN-13 or EAN-8 Barcodes
- Barcode (Code): Code-128, Code-39 or Code-93 Barcodes
- Barcode (other): Codabar, Interleaved2of5 (ITF), ITF-14, UPC-E or PDF-417 Barcodes
Setup
On iOS, the Code Scanner uses the platform-native APIs and can be used out of the box.
On Android, the MLKit Vision Barcode Scanning API will be used, and the model (2.2MB) needs to be included into your app first.
- React Native
- Expo
Inside your gradle.properties
file, add the enableCodeScanner
flag:
VisionCamera_enableCodeScanner=true
Add the enableCodeScanner
flag to your Expo config (app.json
, app.config.json
or app.config.js
):
{
"name": "my app",
"plugins": [
[
"react-native-vision-camera",
{
// ...
"enableCodeScanner": true
}
]
]
}
Usage
To scan codes, simply create a CodeScanner
instance and pass it to the <Camera>
:
- Hooks API
- Imperative API
const codeScanner = useCodeScanner({
codeTypes: ['qr', 'ean-13'],
onCodeScanned: (codes) => {
console.log(`Scanned ${codes.length} codes!`)
}
})
return <Camera {...props} codeScanner={codeScanner} />
The result of this will automatically be memoized.
const codeScanner: CodeScanner = {
codeTypes: ['qr', 'ean-13'],
onCodeScanned: (codes) => {
console.log(`Scanned ${codes.length} codes!`)
}
}
Make sure to memoize the result of this, as every change in this will trigger a Camera session re-build.
render() {
return <Camera {...props} codeScanner={this.codeScanner} />
}
Code result
The Code Scanner will call your onCodeScanned
callback with all detected codes (Code
), including their decoded string value, and their coordinates on the screen relative to subject area of the Code Scanner (the frame
).
UPC-A vs EAN-13 codes
UPC-A is a special case to handle if you need to cater for it. Android's SDK officially supports UPC-A but iOS does not, instead they handle the code as EAN-13. Since EAN-13 is a superset of UPC-A, with an extra 0 digit at the front.
This means, the upc-a
types are reported under the ean-13
umbrella type on iOS:
const codeScanner = useCodeScanner({
codeTypes: ['upc-a'], // <-- ✅ We configure for 'upc-a' types
onCodeScanned: (codes) => {
for (const code of codes) {
console.log(code.type); // <-- ❌ On iOS, we receive 'ean-13'
}
}
})
You will need to keep this in mind and do the conversion from EAN-13 to UPC-A yourself. This can be done by removing the front 0
digit from the code to get a UPC-A code.
Interleaved2of5 (ITF) and ITF-14
Interleaved2of5 (ITF) barcodes are supported by both, Android and iOS, where Android's SDK supports barcodes in ITF format with a minimum length of 6 characters.
ITF-14 is a sub type of interleaved2of5 which always encodes 14 characters. The ITF-14 type is only supported by iOS. If you want to have the restriction to 14 characters in Android as well, you have to handle this in your own code.
Supported Code Types
Code Type | iOS | Android |
---|---|---|
qr | ✅ | ✅ |
aztec | ✅ | ✅ |
data-matrix | ✅ | ✅ |
ean-13 | ✅ | ✅ |
ean-8 |