Added scanning barcodes with a camera
This commit is contained in:
141
quagga2/quagga2-1.12.1/docs/tutorials/first-scan.md
Normal file
141
quagga2/quagga2-1.12.1/docs/tutorials/first-scan.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# Your First Barcode Scan {#first-scan}
|
||||
|
||||
This tutorial walks you through creating a simple barcode scanner using your device's camera.
|
||||
|
||||
## Prerequisites {#prerequisites}
|
||||
|
||||
- A web browser that supports camera access (Chrome, Firefox, Safari, Edge)
|
||||
- A device with a camera
|
||||
- Basic knowledge of HTML and JavaScript
|
||||
|
||||
## Step 1: Set Up the HTML {#step-1-html}
|
||||
|
||||
Create an `index.html` file:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Barcode Scanner</title>
|
||||
<style>
|
||||
#scanner-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 640px;
|
||||
}
|
||||
#scanner-container video {
|
||||
width: 100%;
|
||||
}
|
||||
#result {
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Barcode Scanner</h1>
|
||||
<div id="scanner-container"></div>
|
||||
<div id="result">Scan a barcode...</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/@ericblade/quagga2/dist/quagga.min.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## Step 2: Initialize Quagga {#step-2-initialize}
|
||||
|
||||
Create an `app.js` file:
|
||||
|
||||
```javascript
|
||||
Quagga.init({
|
||||
inputStream: {
|
||||
type: "LiveStream",
|
||||
target: document.querySelector('#scanner-container'),
|
||||
constraints: {
|
||||
facingMode: "environment" // Use back camera
|
||||
}
|
||||
},
|
||||
decoder: {
|
||||
readers: ["code_128_reader", "ean_reader", "upc_reader"]
|
||||
}
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
console.error("Failed to initialize:", err);
|
||||
document.querySelector('#result').textContent = "Error: " + err.message;
|
||||
return;
|
||||
}
|
||||
console.log("Scanner ready");
|
||||
Quagga.start();
|
||||
});
|
||||
```
|
||||
|
||||
## Step 3: Handle Detections {#step-3-handle-detections}
|
||||
|
||||
Add detection handling to `app.js`:
|
||||
|
||||
```javascript
|
||||
Quagga.onDetected(function(result) {
|
||||
const code = result.codeResult.code;
|
||||
const format = result.codeResult.format;
|
||||
|
||||
document.querySelector('#result').textContent =
|
||||
`Found ${format}: ${code}`;
|
||||
|
||||
console.log("Barcode detected:", code);
|
||||
});
|
||||
```
|
||||
|
||||
## Step 4: Run It {#step-4-run}
|
||||
|
||||
1. Serve the files using a local web server (required for camera access)
|
||||
2. Open the page in your browser
|
||||
3. Allow camera access when prompted
|
||||
4. Point the camera at a barcode
|
||||
|
||||
**Note**: Camera access requires HTTPS on non-localhost domains.
|
||||
|
||||
## Complete Code {#complete-code}
|
||||
|
||||
Here's the complete `app.js`:
|
||||
|
||||
```javascript
|
||||
Quagga.init({
|
||||
inputStream: {
|
||||
type: "LiveStream",
|
||||
target: document.querySelector('#scanner-container'),
|
||||
constraints: {
|
||||
facingMode: "environment"
|
||||
}
|
||||
},
|
||||
decoder: {
|
||||
readers: ["code_128_reader", "ean_reader", "upc_reader"]
|
||||
}
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
console.error("Failed to initialize:", err);
|
||||
document.querySelector('#result').textContent = "Error: " + err.message;
|
||||
return;
|
||||
}
|
||||
Quagga.start();
|
||||
});
|
||||
|
||||
Quagga.onDetected(function(result) {
|
||||
const code = result.codeResult.code;
|
||||
const format = result.codeResult.format;
|
||||
document.querySelector('#result').textContent = `Found ${format}: ${code}`;
|
||||
});
|
||||
```
|
||||
|
||||
## Next Steps {#next-steps}
|
||||
|
||||
- [Static Image Scanning](static-image.md) - Decode images without camera
|
||||
- [Configuration Reference](../reference/configuration.md) - Customize behavior
|
||||
- [Tips and Tricks](../how-to-guides/tips-and-tricks.md) - Improve results
|
||||
|
||||
---
|
||||
|
||||
[← Back to Tutorials](index.md)
|
||||
77
quagga2/quagga2-1.12.1/docs/tutorials/index.md
Normal file
77
quagga2/quagga2-1.12.1/docs/tutorials/index.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Tutorials
|
||||
|
||||
Step-by-step tutorials to help you learn Quagga2 by building real examples. These are learning-oriented guides designed to help beginners get hands-on experience.
|
||||
|
||||
## Available Tutorials
|
||||
|
||||
### [Your First Barcode Scan](first-scan.md) ⭐ Start Here
|
||||
Build a complete barcode scanner web app from scratch. You'll learn how to:
|
||||
- Set up HTML structure
|
||||
- Initialize Quagga2
|
||||
- Handle camera permissions
|
||||
- Process detected barcodes
|
||||
- Display results to users
|
||||
|
||||
**Time**: 15 minutes | **Difficulty**: Beginner
|
||||
|
||||
### [Decoding Static Images](static-image.md)
|
||||
Learn to decode barcodes from image files instead of camera feeds. Perfect for:
|
||||
- Photo upload features
|
||||
- Batch processing
|
||||
- Server-side Node.js applications
|
||||
- Testing without a camera
|
||||
|
||||
**Time**: 10 minutes | **Difficulty**: Beginner
|
||||
|
||||
### [Using with React](react-integration.md)
|
||||
Integrate Quagga2 into a React application. Covers:
|
||||
- Component lifecycle management
|
||||
- Handling cleanup
|
||||
- State management
|
||||
- Common pitfalls and solutions
|
||||
|
||||
**Time**: 20 minutes | **Difficulty**: Intermediate
|
||||
|
||||
### [Using with Node.js](node-usage.md)
|
||||
Use Quagga2 in server-side Node.js applications. Learn to:
|
||||
- Process images from filesystem
|
||||
- Handle image buffers
|
||||
- Batch decode multiple images
|
||||
- Build CLI tools
|
||||
|
||||
**Time**: 15 minutes | **Difficulty**: Intermediate
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before starting these tutorials, you should have:
|
||||
|
||||
- Basic HTML/JavaScript knowledge
|
||||
- A text editor
|
||||
- A web server (or ability to run `npx serve`)
|
||||
- A device with a camera (for live scanning tutorials)
|
||||
|
||||
## Tutorial Approach
|
||||
|
||||
These tutorials follow a **learning-by-doing** approach:
|
||||
|
||||
1. **Complete examples** - Each tutorial provides full working code
|
||||
2. **Progressive complexity** - Start simple, add features incrementally
|
||||
3. **Hands-on practice** - Type the code yourself to build muscle memory
|
||||
4. **Real-world scenarios** - Build things you'll actually use
|
||||
|
||||
## Need Help?
|
||||
|
||||
If you get stuck:
|
||||
|
||||
- Check the [API Reference](../reference/api.md) for method details
|
||||
- Review the [Configuration Guide](../reference/configuration.md)
|
||||
- Ask in [Gitter Chat](https://gitter.im/quaggaJS/Lobby)
|
||||
- Search [GitHub Issues](https://github.com/ericblade/quagga2/issues)
|
||||
|
||||
## Contributing
|
||||
|
||||
Found a bug in a tutorial or have an idea for a new one? [Open an issue](https://github.com/ericblade/quagga2/issues) or submit a pull request!
|
||||
|
||||
---
|
||||
|
||||
**Next**: Start with [Your First Barcode Scan](first-scan.md) →
|
||||
182
quagga2/quagga2-1.12.1/docs/tutorials/node-usage.md
Normal file
182
quagga2/quagga2-1.12.1/docs/tutorials/node-usage.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# Using Quagga2 in Node.js {#node-usage}
|
||||
|
||||
This tutorial covers server-side barcode scanning with Quagga2 in Node.js.
|
||||
|
||||
## Installation {#installation}
|
||||
|
||||
```bash
|
||||
npm install @ericblade/quagga2
|
||||
```
|
||||
|
||||
## Basic Usage {#basic-usage}
|
||||
|
||||
```javascript
|
||||
const Quagga = require('@ericblade/quagga2').default;
|
||||
|
||||
Quagga.decodeSingle({
|
||||
src: './barcode.jpg',
|
||||
decoder: {
|
||||
readers: ['code_128_reader', 'ean_reader']
|
||||
}
|
||||
}, function(result) {
|
||||
if (result && result.codeResult) {
|
||||
console.log('Barcode:', result.codeResult.code);
|
||||
console.log('Format:', result.codeResult.format);
|
||||
} else {
|
||||
console.log('No barcode found');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## With Promises {#with-promises}
|
||||
|
||||
Wrap in a Promise for async/await:
|
||||
|
||||
```javascript
|
||||
const Quagga = require('@ericblade/quagga2').default;
|
||||
|
||||
function decodeBarcode(imagePath, readers = ['code_128_reader']) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Quagga.decodeSingle({
|
||||
src: imagePath,
|
||||
decoder: { readers }
|
||||
}, (result) => {
|
||||
if (result && result.codeResult) {
|
||||
resolve(result.codeResult);
|
||||
} else {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const result = await decodeBarcode('./barcode.jpg');
|
||||
if (result) {
|
||||
console.log(`Found ${result.format}: ${result.code}`);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
## Express API Example {#express-example}
|
||||
|
||||
```javascript
|
||||
const express = require('express');
|
||||
const multer = require('multer');
|
||||
const Quagga = require('@ericblade/quagga2').default;
|
||||
|
||||
const app = express();
|
||||
const upload = multer({ dest: 'uploads/' });
|
||||
|
||||
app.post('/scan', upload.single('image'), (req, res) => {
|
||||
if (!req.file) {
|
||||
return res.status(400).json({ error: 'No image provided' });
|
||||
}
|
||||
|
||||
Quagga.decodeSingle({
|
||||
src: req.file.path,
|
||||
decoder: {
|
||||
readers: ['code_128_reader', 'ean_reader', 'upc_reader']
|
||||
}
|
||||
}, (result) => {
|
||||
if (result && result.codeResult) {
|
||||
res.json({
|
||||
code: result.codeResult.code,
|
||||
format: result.codeResult.format
|
||||
});
|
||||
} else {
|
||||
res.json({ code: null, error: 'No barcode found' });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.listen(3000, () => {
|
||||
console.log('Barcode API running on port 3000');
|
||||
});
|
||||
```
|
||||
|
||||
## Batch Processing {#batch-processing}
|
||||
|
||||
Process multiple images:
|
||||
|
||||
```javascript
|
||||
const Quagga = require('@ericblade/quagga2').default;
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
async function decodeImage(imagePath) {
|
||||
return new Promise((resolve) => {
|
||||
Quagga.decodeSingle({
|
||||
src: imagePath,
|
||||
decoder: { readers: ['code_128_reader', 'ean_reader'] }
|
||||
}, (result) => {
|
||||
resolve({
|
||||
file: path.basename(imagePath),
|
||||
code: result?.codeResult?.code || null,
|
||||
format: result?.codeResult?.format || null
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function processDirectory(dir) {
|
||||
const files = fs.readdirSync(dir)
|
||||
.filter(f => /\.(jpg|jpeg|png)$/i.test(f));
|
||||
|
||||
const results = [];
|
||||
for (const file of files) {
|
||||
const result = await decodeImage(path.join(dir, file));
|
||||
results.push(result);
|
||||
console.log(`${result.file}: ${result.code || 'No barcode'}`);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
processDirectory('./images');
|
||||
```
|
||||
|
||||
## Configuration Tips {#configuration-tips}
|
||||
|
||||
### Image Size {#image-size}
|
||||
|
||||
Control processing resolution:
|
||||
|
||||
```javascript
|
||||
Quagga.decodeSingle({
|
||||
src: './large-image.jpg',
|
||||
inputStream: {
|
||||
size: 1280 // Scale to max 1280px
|
||||
},
|
||||
decoder: { readers: ['ean_reader'] }
|
||||
}, callback);
|
||||
```
|
||||
|
||||
### Locator Settings {#locator-settings}
|
||||
|
||||
For difficult images:
|
||||
|
||||
```javascript
|
||||
Quagga.decodeSingle({
|
||||
src: './image.jpg',
|
||||
locate: true,
|
||||
locator: {
|
||||
patchSize: 'small',
|
||||
halfSample: false
|
||||
},
|
||||
decoder: { readers: ['code_128_reader'] }
|
||||
}, callback);
|
||||
```
|
||||
|
||||
## Related {#related}
|
||||
|
||||
- [Static Image Scanning](static-image.md) - Browser-side image decoding
|
||||
- [API Reference](../reference/api.md#quagga-decodesingle) - `decodeSingle()` details
|
||||
- [Configuration Reference](../reference/configuration.md) - All options
|
||||
|
||||
---
|
||||
|
||||
[← Back to Tutorials](index.md)
|
||||
176
quagga2/quagga2-1.12.1/docs/tutorials/react-integration.md
Normal file
176
quagga2/quagga2-1.12.1/docs/tutorials/react-integration.md
Normal file
@@ -0,0 +1,176 @@
|
||||
# Using Quagga2 with React {#react-integration}
|
||||
|
||||
This tutorial shows how to integrate Quagga2 into a React application.
|
||||
|
||||
## Installation {#installation}
|
||||
|
||||
```bash
|
||||
npm install @ericblade/quagga2
|
||||
```
|
||||
|
||||
## Basic Component {#basic-component}
|
||||
|
||||
```jsx
|
||||
import React, { useEffect, useRef, useCallback } from 'react';
|
||||
import Quagga from '@ericblade/quagga2';
|
||||
|
||||
function BarcodeScanner({ onDetected }) {
|
||||
const scannerRef = useRef(null);
|
||||
|
||||
const handleDetected = useCallback((result) => {
|
||||
if (result.codeResult) {
|
||||
onDetected(result.codeResult.code);
|
||||
}
|
||||
}, [onDetected]);
|
||||
|
||||
useEffect(() => {
|
||||
Quagga.init({
|
||||
inputStream: {
|
||||
type: 'LiveStream',
|
||||
target: scannerRef.current,
|
||||
constraints: {
|
||||
facingMode: 'environment'
|
||||
}
|
||||
},
|
||||
decoder: {
|
||||
readers: ['code_128_reader', 'ean_reader']
|
||||
}
|
||||
}, (err) => {
|
||||
if (err) {
|
||||
console.error('Failed to initialize:', err);
|
||||
return;
|
||||
}
|
||||
Quagga.start();
|
||||
});
|
||||
|
||||
Quagga.onDetected(handleDetected);
|
||||
|
||||
return () => {
|
||||
Quagga.offDetected(handleDetected);
|
||||
Quagga.stop();
|
||||
};
|
||||
}, [handleDetected]);
|
||||
|
||||
return <div ref={scannerRef} style={{ width: '100%' }} />;
|
||||
}
|
||||
|
||||
export default BarcodeScanner;
|
||||
```
|
||||
|
||||
## Usage {#usage}
|
||||
|
||||
```jsx
|
||||
import BarcodeScanner from './BarcodeScanner';
|
||||
|
||||
function App() {
|
||||
const handleScan = (code) => {
|
||||
console.log('Scanned:', code);
|
||||
alert(`Barcode: ${code}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Scan a Barcode</h1>
|
||||
<BarcodeScanner onDetected={handleScan} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## With Hooks {#with-hooks}
|
||||
|
||||
Create a reusable hook:
|
||||
|
||||
```jsx
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import Quagga from '@ericblade/quagga2';
|
||||
|
||||
export function useQuagga(config = {}) {
|
||||
const scannerRef = useRef(null);
|
||||
const [scanning, setScanning] = useState(false);
|
||||
const [result, setResult] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!scannerRef.current) return;
|
||||
|
||||
Quagga.init({
|
||||
inputStream: {
|
||||
type: 'LiveStream',
|
||||
target: scannerRef.current,
|
||||
...config.inputStream
|
||||
},
|
||||
decoder: {
|
||||
readers: ['code_128_reader'],
|
||||
...config.decoder
|
||||
},
|
||||
...config
|
||||
}, (err) => {
|
||||
if (!err) {
|
||||
Quagga.start();
|
||||
setScanning(true);
|
||||
}
|
||||
});
|
||||
|
||||
Quagga.onDetected((data) => {
|
||||
setResult(data.codeResult);
|
||||
});
|
||||
|
||||
return () => {
|
||||
Quagga.stop();
|
||||
setScanning(false);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return { scannerRef, scanning, result };
|
||||
}
|
||||
```
|
||||
|
||||
## Stop on Detection {#stop-on-detection}
|
||||
|
||||
```jsx
|
||||
function SingleScanComponent({ onComplete }) {
|
||||
const scannerRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
Quagga.init({
|
||||
inputStream: {
|
||||
type: 'LiveStream',
|
||||
target: scannerRef.current
|
||||
},
|
||||
decoder: {
|
||||
readers: ['ean_reader']
|
||||
}
|
||||
}, (err) => {
|
||||
if (!err) Quagga.start();
|
||||
});
|
||||
|
||||
const handleDetected = (result) => {
|
||||
Quagga.stop();
|
||||
onComplete(result.codeResult.code);
|
||||
};
|
||||
|
||||
Quagga.onDetected(handleDetected);
|
||||
|
||||
return () => {
|
||||
Quagga.offDetected(handleDetected);
|
||||
Quagga.stop();
|
||||
};
|
||||
}, [onComplete]);
|
||||
|
||||
return <div ref={scannerRef} />;
|
||||
}
|
||||
```
|
||||
|
||||
## Resources {#resources}
|
||||
|
||||
- [quagga2-react-example](https://github.com/ericblade/quagga2-react-example/) - Complete example
|
||||
- [quagga2-redux-middleware](https://github.com/ericblade/quagga2-redux-middleware/) - Redux integration
|
||||
|
||||
## Related {#related}
|
||||
|
||||
- [API Reference](../reference/api.md) - Full API documentation
|
||||
- [Configuration Reference](../reference/configuration.md) - All options
|
||||
|
||||
---
|
||||
|
||||
[← Back to Tutorials](index.md)
|
||||
130
quagga2/quagga2-1.12.1/docs/tutorials/static-image.md
Normal file
130
quagga2/quagga2-1.12.1/docs/tutorials/static-image.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Decoding Static Images {#static-image}
|
||||
|
||||
This tutorial shows how to decode barcodes from image files instead of a live camera feed.
|
||||
|
||||
## Basic Usage {#basic-usage}
|
||||
|
||||
Use `Quagga.decodeSingle()` to decode a single image:
|
||||
|
||||
```javascript
|
||||
Quagga.decodeSingle({
|
||||
src: '/path/to/barcode.jpg',
|
||||
decoder: {
|
||||
readers: ["code_128_reader", "ean_reader"]
|
||||
}
|
||||
}, function(result) {
|
||||
if (result && result.codeResult) {
|
||||
console.log("Barcode:", result.codeResult.code);
|
||||
} else {
|
||||
console.log("No barcode found");
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## From File Input {#from-file-input}
|
||||
|
||||
Allow users to upload images:
|
||||
|
||||
### HTML
|
||||
|
||||
```html
|
||||
<input type="file" id="file-input" accept="image/*">
|
||||
<div id="result"></div>
|
||||
```
|
||||
|
||||
### JavaScript
|
||||
|
||||
```javascript
|
||||
document.querySelector('#file-input').addEventListener('change', function(e) {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(event) {
|
||||
Quagga.decodeSingle({
|
||||
src: event.target.result,
|
||||
decoder: {
|
||||
readers: ["code_128_reader", "ean_reader", "upc_reader"]
|
||||
}
|
||||
}, function(result) {
|
||||
if (result && result.codeResult) {
|
||||
document.querySelector('#result').textContent =
|
||||
"Found: " + result.codeResult.code;
|
||||
} else {
|
||||
document.querySelector('#result').textContent = "No barcode found";
|
||||
}
|
||||
});
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
```
|
||||
|
||||
## Controlling Image Size {#controlling-image-size}
|
||||
|
||||
By default, `decodeSingle()` scales images to 800px. Adjust with `inputStream.size`:
|
||||
|
||||
```javascript
|
||||
Quagga.decodeSingle({
|
||||
src: '/path/to/image.jpg',
|
||||
inputStream: {
|
||||
size: 1280 // Process at higher resolution
|
||||
},
|
||||
decoder: {
|
||||
readers: ["ean_reader"]
|
||||
}
|
||||
}, callback);
|
||||
```
|
||||
|
||||
Set `size: 0` to use original image dimensions.
|
||||
|
||||
## With Localization {#with-localization}
|
||||
|
||||
Enable `locate: true` (default) to find barcodes anywhere in the image:
|
||||
|
||||
```javascript
|
||||
Quagga.decodeSingle({
|
||||
src: '/path/to/image.jpg',
|
||||
locate: true,
|
||||
locator: {
|
||||
patchSize: "medium",
|
||||
halfSample: true
|
||||
},
|
||||
decoder: {
|
||||
readers: ["code_128_reader"]
|
||||
}
|
||||
}, function(result) {
|
||||
if (result && result.codeResult) {
|
||||
console.log("Found:", result.codeResult.code);
|
||||
console.log("Location:", result.box); // Bounding box
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Node.js Usage {#nodejs-usage}
|
||||
|
||||
Quagga2 works in Node.js:
|
||||
|
||||
```javascript
|
||||
const Quagga = require('@ericblade/quagga2').default;
|
||||
|
||||
Quagga.decodeSingle({
|
||||
src: './barcode.jpg',
|
||||
decoder: {
|
||||
readers: ["code_128_reader"]
|
||||
}
|
||||
}, function(result) {
|
||||
if (result && result.codeResult) {
|
||||
console.log("Barcode:", result.codeResult.code);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Related {#related}
|
||||
|
||||
- [Your First Scan](first-scan.md) - Live camera scanning
|
||||
- [Node.js Usage](node-usage.md) - Server-side scanning
|
||||
- [API Reference](../reference/api.md#quagga-decodesingle) - `decodeSingle()` details
|
||||
|
||||
---
|
||||
|
||||
[← Back to Tutorials](index.md)
|
||||
Reference in New Issue
Block a user