Skip to content

Commit

Permalink
Merge pull request #65 from serratus/issue-38
Browse files Browse the repository at this point in the history
closes #38 by adding node support
  • Loading branch information
serratus committed Sep 15, 2015
2 parents e5acf19 + b340883 commit a852394
Show file tree
Hide file tree
Showing 25 changed files with 530 additions and 35,063 deletions.
11 changes: 1 addition & 10 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,12 @@ module.exports = function(grunt) {
"typedefs" : {
"deps" : [],
"exports" : "typedefs"
},
"glMatrix" : {
"deps" : ["typedefs"],
"exports" : "glMatrix"
},
"glMatrixAddon" : {
"deps" : ["glMatrix"],
"exports" : "glMatrixAddon"
}
},

"paths" : {
"typedefs" : "typedefs",
"glMatrix" : "vendor/glMatrix",
"glMatrixAddon" : "glMatrixAddon"
"gl-matrix": "../node_modules/gl-matrix/dist/gl-matrix-min"
}
}
}
Expand Down
75 changes: 68 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
quaggaJS
========

- [Changelog](#changelog) (2015-08-29)
- [Changelog](#changelog) (2015-09-15)

## What is QuaggaJS?

Expand Down Expand Up @@ -43,12 +43,12 @@ In cases where real-time decoding is not needed, or the platform does not
support `getUserMedia` QuaggaJS is also capable of decoding image-files using
the File API or other URL sources.

## Getting Started
## Installing

You can simply include `dist/quagga.min.js` in your project and you are ready
to go.
QuaggaJS can be installed using __npm__, __bower__, or by including it with
the __script__ tag.

If you want to keep your project modular, you can also install QuaggaJS via npm:
### NPM

```console
> npm install quagga
Expand All @@ -57,12 +57,33 @@ If you want to keep your project modular, you can also install QuaggaJS via npm:
And then import it as dependency in your project:

```javascript
var quagga = require('quagga');
var Quagga = require('quagga');
```

Currently, the full functionality is only available through the browser. When
using QuaggaJS within __node__, only file-based decoding is available. See the
example for [node_examples](#node-example).

### Bower

You can also install QuaggaJS through __bower__:

```console
> bower install quagga
```

### Script-Tag Anno 1998

You can simply include `dist/quagga.min.js` in your project and you are ready
to go.


## Getting Started

For starters, have a look at the [examples][github_examples] to get an idea
where to go from here.


## <a name="Building">Building</a>

You can build the library yourself by simply cloning the repo and typing:
Expand Down Expand Up @@ -295,7 +316,39 @@ Quagga.decodeSingle({
locate: true, // try to locate the barcode in the image
src: '/test/fixtures/code_128/image-001.jpg' // or 'data:image/jpg;base64,' + data
}, function(result){
console.log(result);
if(result.codeResult) {
console.log("result", result.codeResult.code);
} else {
console.log("not detected");
}
});
```

### <a name="node-example">Using node</a>

The following example illustrates the use of QuaggaJS within a node
environment. It's almost identical to the browser version with the difference
that node does not support web-workers out of the box. Therefore the config
property `numOfWorkers` must be explicitly set to `0`.

```javascript
var Quagga = require('quagga');

Quagga.decodeSingle({
src: "image-abc-123.jpg",
numOfWorkers: 0, // Needs to be 0 when used within node
inputStream: {
size: 800 // restrict input-size to be 800px in width (long-side)
},
decoder: {
readers: ["code_128_reader"] // List of active readers
},
}, function(result) {
if(result.codeResult) {
console.log("result", result.codeResult.code);
} else {
console.log("not detected");
}
});
```

Expand Down Expand Up @@ -377,6 +430,14 @@ on the ``singleChannel`` flag in the configuration when using ``decodeSingle``.

## <a name="changelog">Changelog</a>

### 2015-09-15
Take a look at the release-notes ([0.7.0]
(https://github.com/serratus/quaggaJS/releases/tag/v0.7.0))

- Features
- Added basic support for running QuaggaJS inside __node__ (see [example]
(#node-example))

### 2015-08-29
- Improvements
- Added support for Internet Explorer (only Edge+ supports `getUserMedia`)
Expand Down
2,390 changes: 77 additions & 2,313 deletions dist/quagga.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions dist/quagga.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion example/file_input_require.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,6 @@ <h3>Working with file-input</h3>
</p>
</footer>
<script src="../src/vendor/jquery-1.9.0.min.js" type="text/javascript"></script>
<script data-main="file_input_require.js" src="../src/vendor/require.js"></script>
<script data-main="file_input_require.js" src="../node_modules/requirejs/require.js"></script>
</body>
</html>
17 changes: 4 additions & 13 deletions example/file_input_require.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,16 @@ requirejs.config({
"typedefs" : {
"deps" : [],
"exports" : "typedefs"
},
"glMatrix" : {
"deps" : ["typedefs"],
"exports" : "glMatrix"
},
"glMatrixAddon" : {
"deps" : ["glMatrix"],
"exports" : "glMatrixAddon"
}
},

"paths" : {
"typedefs" : "typedefs",
"glMatrix" : "vendor/glMatrix",
"glMatrixAddon" : "glMatrixAddon"
"gl-matrix": "../node_modules/gl-matrix/dist/gl-matrix-min"
}
});

define(['quagga'], function(Quagga) {
requirejs(['quagga'], function(Quagga) {
var App = {
init: function() {
App.attachListeners();
Expand Down Expand Up @@ -116,13 +107,13 @@ define(['quagga'], function(Quagga) {
singleChannel: false
},
locator: {
patchSize: "large",
patchSize: "medium",
halfSample: true,
showCanvas: true
},
numOfWorkers: 0,
decoder: {
readers: ["i2of5_reader"],
readers: ["code_128_reader"],
showFrequency: true,
showPattern: true
},
Expand Down
21 changes: 21 additions & 0 deletions example/node-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
var Quagga = require('../lib/quagga');

Quagga.decodeSingle({
src: "../test/fixtures/code_128/image-001.jpg",
numOfWorkers: 0,
inputStream: {
size: 800,
area: {
top: "10%",
right: "5%",
left: "5%",
bottom: "10%"
}
}
}, function(result) {
if(result.codeResult) {
console.log("result", result.codeResult.code);
} else {
console.log("not detected");
}
});
2 changes: 1 addition & 1 deletion karma-integration.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ module.exports = function(config) {
frameworks: ['mocha', 'requirejs', 'chai', 'sinon', 'sinon-chai'],
files: [
'test-main.js',
'src/vendor/glMatrix.js',
'src/typedefs.js',
{pattern: 'node_modules/async/lib/async.js', included: false},
{pattern: 'node_modules/gl-matrix/dist/gl-matrix-min.js', included: false},
{pattern: 'src/*.js', included: false},
{pattern: 'spec/**/*integration.spec.js', included: false},
{pattern: 'test/**/*.*', included: false}
Expand Down
2 changes: 1 addition & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ module.exports = function(config) {
frameworks: ['mocha', 'requirejs', 'chai', 'sinon', 'sinon-chai'],
files: [
'test-main.js',
'src/vendor/glMatrix.js',
'src/typedefs.js',
{pattern: 'node_modules/async/lib/async.js', included: false},
{pattern: 'node_modules/gl-matrix/dist/gl-matrix-min.js', included: false},
{pattern: 'src/*.js', included: false},
{pattern: 'spec/**/*.js', included: false},
{pattern: 'test/**/*.*', included: false}
Expand Down
101 changes: 101 additions & 0 deletions lib/frame_grabber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/* jshint undef: true, unused: true, browser:true, devel: true */
/* global define */

define(["cv_utils"], function(CVUtils) {
"use strict";

var Ndarray = require("ndarray"),
Interp2D = require("ndarray-linear-interpolate").d2;

var FrameGrabber = {};

FrameGrabber.create = function(inputStream) {
var _that = {},
_streamConfig = inputStream.getConfig(),
_video_size = CVUtils.imageRef(inputStream.getRealWidth(), inputStream.getRealHeight()),
_canvasSize = inputStream.getCanvasSize(),
_size = CVUtils.imageRef(inputStream.getWidth(), inputStream.getHeight()),
_topRight = inputStream.getTopRight(),
_data = new Uint8Array(_size.x * _size.y),
_grayData = new Uint8Array(_video_size.x * _video_size.y),
_canvasData = new Uint8Array(_canvasSize.x * _canvasSize.y),
_grayImageArray = Ndarray(_grayData, [_video_size.y, _video_size.x]).transpose(1, 0),
_canvasImageArray = Ndarray(_canvasData, [_canvasSize.y, _canvasSize.x]).transpose(1, 0),
_targetImageArray = _canvasImageArray.hi(_topRight.x + _size.x, _topRight.y + _size.y).lo(_topRight.x, _topRight.y),
_stepSizeX = _video_size.x/_canvasSize.x,
_stepSizeY = _video_size.y/_canvasSize.y;

console.log("FrameGrabber", JSON.stringify({
videoSize: _grayImageArray.shape,
canvasSize: _canvasImageArray.shape,
stepSize: [_stepSizeX, _stepSizeY],
size: _targetImageArray.shape,
topRight: _topRight
}));

/**
* Uses the given array as frame-buffer
*/
_that.attachData = function(data) {
_data = data;
};

/**
* Returns the used frame-buffer
*/
_that.getData = function() {
return _data;
};

/**
* Fetches a frame from the input-stream and puts into the frame-buffer.
* The image-data is converted to gray-scale and then half-sampled if configured.
*/
_that.grab = function() {
var frame = inputStream.getFrame();

if (frame) {
this.scaleAndCrop(frame);
return true;
} else {
return false;
}
};

_that.scaleAndCrop = function(frame) {
var x,
y;

// 1. compute full-sized gray image
CVUtils.computeGray(frame.data, _grayData);

// 2. interpolate
for (y = 0; y < _canvasSize.y; y++) {
for (x = 0; x < _canvasSize.x; x++) {
_canvasImageArray.set(x, y, (Interp2D(_grayImageArray, x * _stepSizeX, y * _stepSizeY)) | 0);
}
}

// targetImageArray must be equal to targetSize
if (_targetImageArray.shape[0] !== _size.x ||
_targetImageArray.shape[1] !== _size.y) {
throw new Error("Shapes do not match!");
}

// 3. crop
for (y = 0; y < _size.y; y++) {
for (x = 0; x < _size.x; x++) {
_data[y * _size.x + x] = _targetImageArray.get(x, y);
}
}
},

_that.getSize = function() {
return _size;
};

return _that;
};

return (FrameGrabber);
});
Loading

0 comments on commit a852394

Please sign in to comment.