Added scanning barcodes with a camera

This commit is contained in:
2026-03-08 16:59:33 +00:00
parent b4f8489834
commit 5a37e5dd5f
404 changed files with 224181 additions and 0 deletions

View 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)

View 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) →

View 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)

View 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)

View 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)