barcode
Version:
Generate 1D and 2D barcodes
115 lines (98 loc) • 2.81 kB
JavaScript
/*
* barcode generator - code39
*/
var gm = require('gm');
const bmap = {
' ': [0,1,1,0,0,0,1,0,0],
'$': [0,1,0,1,0,1,0,0,0],
'%': [0,0,0,1,0,1,0,1,0],
'*': [0,1,0,0,1,0,1,0,0], // Start/stop marker
'+': [0,1,0,0,0,1,0,1,0],
'|': [0,1,0,0,0,0,1,0,1],
'.': [1,1,0,0,0,0,1,0,0],
'/': [0,1,0,1,0,0,0,1,0],
'-': [0,1,0,0,0,0,1,0,1],
'0': [0,0,0,1,1,0,1,0,0],
'1': [1,0,0,1,0,0,0,0,1],
'2': [0,0,1,1,0,0,0,0,1],
'3': [1,0,1,1,0,0,0,0,0],
'4': [0,0,0,1,1,0,0,0,1],
'5': [1,0,0,1,1,0,0,0,0],
'6': [0,0,1,1,1,0,0,0,0],
'7': [0,0,0,1,0,0,1,0,1],
'8': [1,0,0,1,0,0,1,0,0],
'9': [0,0,1,1,0,0,1,0,0],
'A': [1,0,0,0,0,1,0,0,1],
'B': [0,0,1,0,0,1,0,0,1],
'C': [1,0,1,0,0,1,0,0,0],
'D': [0,0,0,0,1,1,0,0,1],
'E': [1,0,0,0,1,1,0,0,0],
'F': [0,0,1,0,1,1,0,0,0],
'G': [0,0,0,0,0,1,1,0,1],
'H': [1,0,0,0,0,1,1,0,0],
'I': [0,0,1,0,0,1,1,0,0],
'J': [0,0,0,0,1,1,1,0,0],
'K': [1,0,0,0,0,0,0,1,1],
'L': [0,0,1,0,0,0,0,1,1],
'M': [1,0,1,0,0,0,0,1,0],
'N': [0,0,0,0,1,0,0,1,1],
'O': [1,0,0,0,1,0,0,1,0],
'P': [0,0,1,0,1,0,0,1,0],
'Q': [0,0,0,0,0,0,1,1,1],
'R': [1,0,0,0,0,0,1,1,0],
'S': [0,0,1,0,0,0,1,1,0],
'T': [0,0,0,0,1,0,1,1,0],
'U': [1,1,0,0,0,0,0,0,1],
'V': [0,1,1,0,0,0,0,0,1],
'W': [1,1,1,0,0,0,0,0,0],
'X': [0,1,0,0,1,0,0,0,1],
'Y': [1,1,0,0,1,0,0,0,0],
'Z': [0,1,1,0,1,0,0,0,0]
};
const NARROW_BAR = 20;
const WIDE_BAR = 55;
const QUIET_BAR = 35;
const SYM_LEN = 6 * NARROW_BAR + 3 * WIDE_BAR + QUIET_BAR;
module.exports.createCode = function (options, callback) {
if (!options.w || !options.h) {
return callback(new Error('Width and Height must be non-zero'), {});
}
options.data = options.data.trim();
if (!options.data) {
return callback(new Error('No data given'), {});
}
options.data = ('*' + options.data + '*').toUpperCase();
var wQuotient = options.w / (options.data.length * SYM_LEN - QUIET_BAR);
var nBarWidth = NARROW_BAR * wQuotient >> 0;
var wBarWidth = WIDE_BAR * wQuotient >> 0;
var qBarWidth = QUIET_BAR * wQuotient >> 0;
if (nBarWidth < 1 || qBarWidth == nBarWidth) {
return callback(new Error('Current settings will result in a ' +
'degenerate barcode'), {});
}
var img = gm(options.w, options.h, options.bgcolor),
count = 0,
pos = 0,
ch,
w;
img.stroke(options.barcolor, 1);
for(var k in options.data) {
if (count++) {
pos += qBarWidth;
}
ch = bmap[options.data[k]] || bmap[' '];
for(var j in ch) {
w = ch[j] ? wBarWidth : nBarWidth;
if ( !(j % 2) ) {
// workaround for GM - cannot set gravity on stroke
for (var m = 0; m < w; m++) {
img.drawLine(pos + m, 0, pos + m, options.h);
}
}
pos += w;
}
}
img.stream(options.type, function (err, stdout, stderr) {
callback(err, stdout);
});
};