238 lines
5.4 KiB
JavaScript
238 lines
5.4 KiB
JavaScript
/*
|
|
*copyright Ryan Day 2012
|
|
*
|
|
* Licensed under the MIT license:
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
*
|
|
* this is the main server side application file for node-qrcode.
|
|
* these exports use serverside canvas api methods for file IO and buffers
|
|
*
|
|
*/
|
|
|
|
var QRCodeLib = require('./lib/qrcode-draw')
|
|
, terminalRender = require('./lib/termialrender.js')
|
|
, svgRender = require('./lib/svgrender')
|
|
, Canvas = require('canvas')
|
|
, fs = require('fs');
|
|
|
|
|
|
var QRCodeDraw = QRCodeLib.QRCodeDraw,
|
|
QRCode = QRCodeLib.QRCode;
|
|
|
|
//EXPORTS
|
|
|
|
//
|
|
// breaking change to 0.1 this used to be an instance. now it returns the constructor.
|
|
//
|
|
exports.QRCodeDraw = QRCodeDraw;
|
|
|
|
//
|
|
// export error correct levels.
|
|
//
|
|
exports.errorCorrectLevels = QRCodeLib.QRErrorCorrectLevel;
|
|
|
|
//
|
|
// export original canvas to be used with draw method, esp. Canvas.Image
|
|
//
|
|
exports.canvas=Canvas;
|
|
|
|
/*
|
|
* provide an api to return the max characters allowed for given dimensions, and miniumum error correction level
|
|
* the qr code library will always use the maximum error correction level for the given numbar of chars constrained by size
|
|
*/
|
|
exports.getMaxChars = function(minErrorCorrectionLevel,width,moduleScale){
|
|
//TODO THIS NEEDS TO WORK
|
|
console.log('this doesnt work yet. comming soon =)');
|
|
};
|
|
|
|
var parseOptions = function(options) {
|
|
var textKeys = {'minimum':"L",'medium':"M",'high':"Q",'max':"H"}
|
|
if(options.errorCorrectLevel) {
|
|
var ec = options.errorCorrectLevel;
|
|
if(textKeys[ec]){
|
|
options.errorCorrectLevel = textKeys[ec];
|
|
}
|
|
}
|
|
return options;
|
|
};
|
|
|
|
// returns Canvas Object with qr code drawn on it
|
|
/*
|
|
* String text, optional Object options, Function callback
|
|
*/
|
|
var draw = exports.draw = function(text,options,cb){
|
|
|
|
var args = Array.prototype.slice.call(arguments);
|
|
cb = args.pop();
|
|
if(typeof cb != 'function') {
|
|
throw new TypeError('last argument must be a function');
|
|
}
|
|
|
|
text = args.shift();
|
|
options = args.shift()||{};
|
|
options=parseOptions(options);
|
|
|
|
//NOTE the width and height are determined from within the qr code lib and are not configurable from the outside yet
|
|
|
|
var drawInstance = new QRCodeDraw();
|
|
drawInstance.draw(new Canvas(200,200),text,options,function(error,canvas,qrWidth){
|
|
cb(error,canvas,qrWidth)
|
|
});
|
|
};
|
|
|
|
//returns data uri for drawn qrcode png
|
|
exports.toDataURL = exports.toDataURI = function(text,options,cb){
|
|
|
|
if(typeof options == 'function') {
|
|
cb = options;
|
|
options = {};
|
|
}
|
|
|
|
draw(text,options,function(error,canvas){
|
|
if(error) {
|
|
cb(error);
|
|
} else {
|
|
canvas.toDataURL(cb);
|
|
}
|
|
});
|
|
}
|
|
|
|
//synchronous PNGStream
|
|
exports.toPNGStream = function (text, WSpath, options,cb) {
|
|
|
|
if(typeof options == 'function'){
|
|
cb = options;
|
|
options = {};
|
|
}
|
|
|
|
var out = fs.createWriteStream(WSpath);
|
|
|
|
draw(text, options, function (error,canvas) {
|
|
if(error) {
|
|
cb(error,'');
|
|
} else {
|
|
stream = canvas.createPNGStream();
|
|
}
|
|
|
|
stream.pipe(out);
|
|
|
|
stream.on('end', function () {
|
|
cb(error,'');
|
|
});
|
|
|
|
stream.pipe(out);
|
|
|
|
});
|
|
|
|
return out;
|
|
}
|
|
|
|
//returns bytes written to file
|
|
exports.save = function(path,text,options,cb){
|
|
|
|
if(typeof options == 'function'){
|
|
cb = options;
|
|
options = {};
|
|
}
|
|
|
|
var fileExt = path.slice((path.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
|
|
|
|
if (fileExt === 'svg') {
|
|
saveSvg(path,text,options,cb);
|
|
} else {
|
|
savePng(path,text,options,cb);
|
|
}
|
|
};
|
|
|
|
function savePng(path,text,options,cb){
|
|
draw(text, options, function(error,canvas){
|
|
|
|
var fd,buf,fdAndBuf = function(){
|
|
fs.write(fd, buf, 0, buf.length, 0, function(fsErr, written){
|
|
fs.close(fd);
|
|
if(cb) cb(fsErr, written);
|
|
});
|
|
};
|
|
|
|
//run non dependent async calls at the same time ish
|
|
canvas.toBuffer(function(canvasErr, _buf){
|
|
if(canvasErr) return cb(canvasErr);
|
|
buf = _buf
|
|
if(fd) fdAndBuf();
|
|
});
|
|
|
|
fs.open(path, 'w', 0666, function(fsErr,_fd){
|
|
if(fsErr) return cb(fsErr);
|
|
fd = _fd
|
|
if(buf) fdAndBuf();
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
function saveSvg(path,text,options,cb){
|
|
exports.drawSvg(text,function(error,code){
|
|
if (!error) {
|
|
fs.writeFile(path, code, function(fsErr) {
|
|
return cb(fsErr, fsErr ? null : code);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
//
|
|
//this returns an array of points that have either a 0 or 1 value representing 0 for light and 1 for dark
|
|
//these values include points in the white edge of the qrcode because that edge is actually part of the spec
|
|
//
|
|
exports.drawBitArray = function(text,options,cb){
|
|
|
|
if(typeof options == 'function'){
|
|
cb = options;
|
|
options = {};
|
|
}
|
|
options = parseOptions(options);
|
|
|
|
var drawInstance = new QRCodeDraw();
|
|
drawInstance.drawBitArray(text,options,function(error,bits,width){
|
|
cb(error,bits,width);
|
|
});
|
|
}
|
|
|
|
//
|
|
// draw qr in your terminal!
|
|
//
|
|
exports.drawText = function(text,options,cb){
|
|
|
|
if(typeof options == 'function'){
|
|
cb = options;
|
|
options = {};
|
|
}
|
|
|
|
var drawInstance = new QRCodeDraw();
|
|
drawInstance.drawBitArray(text,function(error,bits,width){
|
|
if (!error) {
|
|
var code = terminalRender.renderBits(bits,width);
|
|
cb(error,code);
|
|
} else {
|
|
cb(error,null);
|
|
}
|
|
});
|
|
}
|
|
|
|
exports.drawSvg = function(text,options,cb){
|
|
if(typeof options == 'function'){
|
|
cb = options;
|
|
options = {};
|
|
}
|
|
|
|
var drawInstance = new QRCodeDraw();
|
|
drawInstance.drawBitArray(text,function(error,bits,width){
|
|
if (!error) {
|
|
var code = svgRender.renderBits(bits,width,options);
|
|
cb(error,code);
|
|
} else {
|
|
cb(error,null);
|
|
}
|
|
});
|
|
}
|