Skip to content

Instantly share code, notes, and snippets.

@getchenge
Last active August 29, 2015 14:16
Show Gist options
  • Save getchenge/a69fe38cdb8c2a46b84d to your computer and use it in GitHub Desktop.
Save getchenge/a69fe38cdb8c2a46b84d to your computer and use it in GitHub Desktop.
a qrcode-service by nodejs
//npm install qrcode
"use strict";
var _ = require('lodash');
var aid = require(__base + 'lib/aid');
var defaultNumber = aid.defaultNumber();
function resample_hermite(canvas, W, H, W2, H2) {
var time1 = Date.now();
W2 = Math.round(W2);
H2 = Math.round(H2);
var img = canvas.getContext("2d").getImageData(0, 0, W, H);
var img2 = canvas.getContext("2d").getImageData(0, 0, W2, H2);
var data = img.data;
var data2 = img2.data;
var ratio_w = W / W2;
var ratio_h = H / H2;
var ratio_w_half = Math.ceil(ratio_w / 2);
var ratio_h_half = Math.ceil(ratio_h / 2);
for (var j = 0; j < H2; j++) {
for (var i = 0; i < W2; i++) {
var x2 = (i + j * W2) * 4;
var weight = 0;
var weights = 0;
var weights_alpha = 0;
var gx_g, gx_b, gx_a;
var gx_r = gx_g = gx_b = gx_a = 0;
var center_y = (j + 0.5) * ratio_h;
for (var yy = Math.floor(j * ratio_h); yy < (j + 1) * ratio_h; yy++) {
var dy = Math.abs(center_y - (yy + 0.5)) / ratio_h_half;
var center_x = (i + 0.5) * ratio_w;
var w0 = dy * dy //pre-calc part of w
for (var xx = Math.floor(i * ratio_w); xx < (i + 1) * ratio_w; xx++) {
var dx = Math.abs(center_x - (xx + 0.5)) / ratio_w_half;
var w = Math.sqrt(w0 + dx * dx);
if (w >= -1 && w <= 1) {
//hermite filter
weight = 2 * w * w * w - 3 * w * w + 1;
if (weight > 0) {
dx = 4 * (xx + yy * W);
//alpha
gx_a += weight * data[dx + 3];
weights_alpha += weight;
//colors
if (data[dx + 3] < 255)
weight = weight * data[dx + 3] / 250;
gx_r += weight * data[dx];
gx_g += weight * data[dx + 1];
gx_b += weight * data[dx + 2];
weights += weight;
}
}
}
}
data2[x2] = gx_r / weights;
data2[x2 + 1] = gx_g / weights;
data2[x2 + 2] = gx_b / weights;
data2[x2 + 3] = gx_a / weights_alpha;
}
}
//console.log("hermite = " + (Math.round(Date.now() - time1) / 1000) + " s");
canvas.getContext("2d").clearRect(0, 0, Math.max(W, W2), Math.max(H, H2));
canvas.width = W2;
canvas.height = H2;
canvas.getContext("2d").putImageData(img2, 0, 0);
return canvas;
}
function defaultNumber(val, default_val) {
val = +val;
if (typeof val == 'number' && !isNaN(val)) {
return val;
} else {
return default_val;
}
}
module.exports = function (req, res) {
var params = req.query || {};
var QRCode = require('qrcode');
var draw = new QRCode.QRCodeDraw();
var Canvas = QRCode.canvas;
var content = params['content'] || 'hello';
var width = params['width'];
var errorLevelObj = {//容错率等级 L M Q H
L: 1,
M: 0,
Q: 3,
H: 2
};
var errorlevel = params['errorlevel'] && params['errorlevel'].toUpperCase();
var margin = +params['margin'];
//draw.color = {
// dark: '#333',
// light: '#efefef'
//};
draw.scale = defaultNumber(params['scale'], 10);//黑点尺寸
draw.defaultErrorCorrectLevel = typeof errorLevelObj[errorlevel] == 'number' ? errorLevelObj[errorlevel] : 1;
draw.marginScaleFactor = 0;//边距点个数
draw.defaultMargin = defaultNumber(params['margin'], 10);
//if (_.isNumber(margin) && !_.isNaN(margin)) {//边距大小,像素
// draw.defaultMargin = margin;
//} else {
// draw.defaultMargin = 10;
//}
//draw.draw(new Canvas(200, 200), content, {version: +params['level'] || 10}, function (error, canvas) {//設置容量等級
draw.draw(new Canvas(200, 200), content, function (error, canvas) {
if (width) {
canvas = resample_hermite(canvas, canvas.width, canvas.height, width, width);//重置canvas大小
}
canvas.toDataURL(function (err, url) {//转换为二进制以图片格式输出
url = url.replace('data:image/png;base64,', '');
url = new Buffer(url, 'base64');
res.type('png');
res.end(url, 'binary');
});
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment