node-qrcode-lite/test/clientsideserver.js
2016-08-16 06:29:42 -07:00

302 lines
6.9 KiB
JavaScript

var express = require('express')
,app = express.createServer()
,fs = require('fs')
,QRCode = require('../qrcode')
,canvasutil = require('canvasutil')
,Canvas = require('canvas')
,Image = Canvas.Image;
var path = require('path')
app.configure(function(){
app.use(express.methodOverride());
app.use(express.bodyParser());
app.use(app.router);
app.use(express.static(path.resolve(__dirname,'..')));
});
app.get('/', function(req, res){
fs.readFile(path.join(__dirname,'clientside.html'), function (err, data) {
res.send(data?data.toString():err);
});
});
var effectHandlers = {};
app.get('/generate', function(req, res){
var q = req.query||{},imageSrc;
QRCode.QRCodeDraw.color.light = q.lightColor||'#ffffff';
QRCode.QRCodeDraw.color.dark = q.darkColor||'#000000';
QRCode.QRCodeDraw.scale = +(q.scale);
if(isNaN(QRCode.QRCodeDraw.scale)) QRCode.QRCodeDraw.scale = 4;
//NOTE when i set scale to 500 something seg faulted
if(QRCode.QRCodeDraw.scale > 50) QRCode.QRCodeDraw.scale = 50;
var effect = q.effect||'plain';
if(!effectHandlers[effect]){
effect = 'plain';
}
effectHandlers[effect](q,function(error,canvas){
if(!error){
canvas.toBuffer(function(err, buf){
res.header('Content-Type','image/png');
res.send(buf);
});
} else {
var msg = error.message+"\n"+error.stack;
res.header('Content-Type','text/plain');
res.send(msg);
console.error(msg);
}
});
});
effectHandlers.node = function(args,cb){
args.src = path.join(__dirname,'fixtures','node_logo.png');
this.image(path.join(args,cb);
};
effectHandlers.npm = function(args,cb){
args.src = path.join(__dirname,'fixtures','npm_logo.png');
this.image(args,cb);
};
effectHandlers.bacon = function(args,cb){
args.src = path.join(__dirname,'fixtures','bacon-love.png');
this.image(args,cb);
};
effectHandlers.baconBikini = function(args,cb){
args.src = path.join(__dirname,'fixtures','bacon-bikini.png');
this.image(args,cb);
};
effectHandlers.rounded = function(args,cb){
QRCode.draw(args.text||'',function(err,canvas){
if(err) {
cb(err,canvas);
return;
}
var tpx = new canvasutil.PixelCore()
,luma709Only = canvasutil.conversionLib.luma709Only
,savedBuffer
,up=[],down=[],left=[],right=[]
,upPx,downPx,leftPx,rightPx,undefined,r,t,l,b,corner = 0;
tpx.threshold = 100;
tpx.iterate(canvas,function(px,i,len,pixels,w,h,pixelCore){
corner = 0;
//is dark
if(luma709Only(px.r,px.g,px.b) < pixelCore.threshold) {
if(i-w > 0){
upPx = (i-w)*4;
up[0] = pixels[upPx + 0];
up[1] = pixels[upPx + 1];
up[2] = pixels[upPx + 2];
//console.log('up',up);
}
if(i+w <= len) {
downPx = (i+w)*4;
down[0] = pixels[downPx + 0];
down[1] = pixels[downPx + 1];
down[2] = pixels[downPx + 2];
//console.log('down',down);
}
//have left pixel but no wrapping
if(i%w != 0){
leftPx = (i-1)*4;
left[0] = pixels[leftPx + 0];
left[1] = pixels[leftPx + 1];
left[2] = pixels[leftPx + 2];
//console.log('left',left);
}
if(i%w != w-1){
rightPx = (i+1)*4;
right[0] = pixels[rightPx + 0];
right[1] = pixels[rightPx + 1];
right[2] = pixels[rightPx + 2];
//console.log('right',right);
}
r = rightPx?luma709Only(right[0],right[1],right[2]):0;
t = upPx?luma709Only(up[0],up[1],up[2]):0;
l = leftPx?luma709Only(left[0],left[1],left[2]):0;
d = downPx?luma709Only(down[0],down[1],down[2]):0;
if(l > pixelCore.threshold){//if left is light and i am dark
if(t > pixelCore.threshold){//if top is light and i am dark
corner = 1;
pixels[rightPx + 4] = 100;
} else if(d > pixelCore.threshold){//if bottom is light and i am dark
pixels[rightPx + 4] = 100;
corner = 1;
}
} else if(r > pixelCore.threshold){
if(t > pixelCore.threshold){//if top is light and i am dark
corner = 1;
} else if(d > pixelCore.threshold){//if bottom is light and i am dark
corner = 1;
}
}
if(corner) {
px.a = 50;
}
}
});
cb(false,canvas);
});
};
effectHandlers.remoteImage = function(args,cb){
var src = args.src,domain,uri;
if(!src) {
cb(new Error('src required'),null);
} else {
if(src.indexof('://') != -1){
src = src.split('://').unshift();
var parts = src.split('/');
domain = parts.shift();
uri = parts.join('/');
}
}
if(!domain || !uri) {
cb(new Error('missing domain or uri '+args.src));
return;
}
var options = {
host: domain,
port: 80,
path: uri,
method: 'GET'
}
,req = http.request(options, function(res) {
if(res.statusCode < 200 || res.statusCode > 299){
cb(new Error('http '+res.statusCode+' response code'),null);
return;
}
res.setEncoding('utf8');
var data = '';
res.on('data', function (chunk) {
data += chunk;
console.log('BODY: ' + chunk);
});
res.on('complete',function(){
cb(false,data);
});
res.on('error',function(error){
cb(error,null);
cb = function(){};
});
});
req.end();
};
effectHandlers.image = function(args,cb){
src = args.src||'';
var img = new Image(),convert = canvasutil.conversionLib;
img.onload = function(){
QRCode.draw(args.text||'',function(err,canvas){
if(err) {
cb(err,false);
return;
}
var codeCtx = canvas.getContext('2d')
, frame = codeCtx.getImageData(0,0,canvas.width,canvas.width)
, tpx = new canvasutil.PixelCore()
, baconCanvas = new Canvas(canvas.width,canvas.width)
, ctx = baconCanvas.getContext('2d')
,topThreshold = args.darkThreshold||25
,bottomThreshold = args.lightThreshold||75;
tpx.threshold = 50;
//scale image
var w = canvas.width;
var h = canvas.height;
if(img.width>img.height) {
w = w*(canvas.height/h)
h = canvas.height;
} else {
h = h*(canvas.height/w)
w = canvas.width;
}
ctx.drawImage(img,0,0,w,h);
try{
tpx.iterate(baconCanvas,function(px,i,l,pixels,w,h,pixelCore){
var luma = (0.2125*px.r + 0.7154*px.g + 0.0721*px.b)
, codeLuma = convert.luma709Only(frame.data[i*4],frame.data[i*4+1],frame.data[i*4+2]);
if(codeLuma > pixelCore.threshold){
if(luma < bottomThreshold) {
var yuv = convert.rgbToYuv(px.r,px.g,px.b),rgb;
rgb = convert.yuvToRgb(bottomThreshold,yuv[1],yuv[2]);
px.r = rgb[0];
px.g = rgb[1];
px.b = rgb[2];
px.a = 255;
}
} else {
if(luma > topThreshold) {
var yuv = convert.rgbToYuv(px.r,px.g,px.b),rgb;
rgb = convert.yuvToRgb(topThreshold,yuv[1],yuv[2]);
px.r = rgb[0];
px.g = rgb[1];
px.b = rgb[2];
}
}
});
} catch(e){
cb(err,false);
}
cb(false,baconCanvas);
});
};
img.onerror = function(error){
error.message += ' ('+src+')';
cb(error,null);
}
img.src = src;
};
effectHandlers.plain = function(args,cb){
var text = args.text||'';
QRCode.draw(text||'',function(err,canvas){
cb(err,canvas);
});
};
app.listen(3031);
console.log('listening on 3031');