Reading barcodes with QuaggaJS
Step 1 - Coding the view mybarcodeview.php
The view mybarcodeview.php
must be installed into the INSTALL_DIR/applications/default/app/view/
folder.
<form id="barcode-form"/>
is the HTML form that embeds the Start andStop
buttons of the camera and that displays the barcode number once decoded.<div id="live-camera"/>
is the HTML container of the camera stream.- By clicking on the Start button, the
Quagga.init()
function initializes the Quagga library for the configuration set through theliveStreamConfig
variable and then requests for camera access. Next, if no error is detected, the video-stream is started by a call to thestartScan()
JS function (that finally callsQuagga.start()
). - By clicking on the Stop button, the camera is disconnected through a call to the
stopScan()
JS function (in turn by a call toQuagga.stop()
). - The
Quagga.onProcessed()
method registers a callback function that draws frames around possible barcodes on the video-stream. - Finally, the
Quagga.onDetected()
method registers the function called once a barcode has been decoded. The barcode number is displayed in the Decoded barcode field and the camera-stream is stopped.
View mybarcodeview.php
<form id="barcode-form" class="w3-padding-16">
<label>Decoded barcode</label><br>
<input class="w3-input w3-border" type="search" placeholder="Click on Start for scanning a barcode..." readonly><br>
<button class="start w3-btn w3-green" type="button"><i class="fa fa-play"></i> Start</button>
<button class="stop w3-btn w3-red w3-hide" type="button"><i class="fa fa-stop"></i> Stop</button>
</form>
<div id="live-camera" class="w3-hide">
</div>
<style>
#live-camera {
position: relative;
width: 100%;
height: auto;
overflow: hidden;
text-align: center;}
#live-camera > canvas,
#live-camera > video {
max-width: 100%;
width: 100%;
}
#live-camera > canvas.drawing,
#live-camera > canvas.drawingBuffer {
position: absolute;
left: 0; top: 0;
}
</style>
<script>
console.log('mybarcodeview.php');
var liveStreamConfig = {
inputStream: {
type: "LiveStream",
target: '#live-camera',
constraints: {
width: {min: 640},
height: {min: 480},
aspectRatio: {min: 1, max: 100},
facingMode: "environment" // or "user" for the front camera
}
},
locator: {
patchSize: "medium",
halfSample: true
},
numOfWorkers: (navigator.hardwareConcurrency ? navigator.hardwareConcurrency : 4),
decoder: {
"readers": [
{"format": "ean_reader", "config": {}}
]
},
locate: true
};
// The fallback to the file API requires a different inputStream option.
// The rest is the same
var fileConfig = $.extend(
{},
liveStreamConfig,
{
inputStream: {
size: 800
}
}
);
// Start the live stream scanner when the start button is clicked on
$('#barcode-form button.start').on('click', function () {
Quagga.init(
liveStreamConfig,
function (err) {
if (err) {
znetdkMobile.messages.add('error', err.name, err.message);
stopScan();
return;
}
startScan();
}
);
});
$('#barcode-form button.stop').on('click', function () {
stopScan();
});
// Make sure, QuaggaJS draws frames an lines around possible
// barcodes on the live stream
Quagga.onProcessed(function (result) {
var drawingCtx = Quagga.canvas.ctx.overlay,
drawingCanvas = Quagga.canvas.dom.overlay;
if (result) {
if (result.boxes) {
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")),
parseInt(drawingCanvas.getAttribute("height")));
result.boxes.filter(function (box) {
return box !== result.box;
}).forEach(function (box) {
Quagga.ImageDebug.drawPath(box, {x: 0, y: 1}, drawingCtx, {color: "green", lineWidth: 2});
});
}
if (result.box) {
Quagga.ImageDebug.drawPath(result.box, {x: 0, y: 1}, drawingCtx, {color: "#00F", lineWidth: 2});
}
if (result.codeResult && result.codeResult.code) {
Quagga.ImageDebug.drawPath(result.line, {x: 'x', y: 'y'}, drawingCtx, {color: 'red', lineWidth: 3});
}
}
});
// Once a barcode had been read successfully, stop quagga
Quagga.onDetected(function (result) {
if (result.codeResult.code) {
$('#barcode-form input').val(result.codeResult.code);
$('#barcode-form input').addClass('w3-pale-green');
stopScan();
znetdkMobile.messages.add('info', 'Information', 'Barcode decoded successfully.');
}
});
function startScan() {
$('#barcode-form input').removeClass('w3-pale-green');
$('#barcode-form input').val('');
Quagga.start();
$('#live-camera').removeClass('w3-hide');
$('#barcode-form button.start').addClass('w3-hide');
$('#barcode-form button.stop').removeClass('w3-hide');
znetdkMobile.messages.showSnackbar('Scan in progress...');
}
function stopScan() {
Quagga.stop();
$('#live-camera').addClass('w3-hide');
$('#barcode-form button.stop').addClass('w3-hide');
$('#barcode-form button.start').removeClass('w3-hide');
znetdkMobile.messages.showSnackbar('Scan terminated.');
}
</script>
HTML5
JS
Step 2 - Loading the QuaggaJS library
The QuaggaJS library is automatically loaded by specifying into the config.php
of the Web App, the matching url on the CDN hosting (see Settings | App extra CSS and JS libraries).
The config.php
script is located into the INSTALL_DIR/applications/default/app/
folder.
The line below can be inserted anywhere in the config.php
script.
Script config.php
define('CFG_APP_JS', 'https://cdnjs.cloudflare.com/ajax/libs/quagga/0.12.1/quagga.min.js');
PHP
Step 3 - Adding "EAN-13 barcode" item to the navigation menu
Finally, to give users access to the mybarcodeview.php
bar chart view, a menu item definition is added into the menu.php
script of the Web App (see Get Started | New menu items for more information).
The menu.php
script is located into the INSTALL_DIR/applications/default/app/
folder.
Script menu.php
static public function initAppMenuItems() {
// ... Here, some menu items...
\MenuManager::addMenuItem(NULL, 'mybarcodeview', 'EAN-13 barcode', 'fa-barcode');
// ... Here, other menu items...
}
PHP