var Detector = require('./lib/Detector'); var Decoder = require('./lib/Decoder'); var debug = false; // 获取指定位置的灰度 var Pixel = function (data,base) { return function(x,y){ if (base.width < x || base.height < y) { throw "point error"; } var point = (x * 4) + (y * base.width * 4) return (data[point] * 33.33 + data[point + 1] * 33.33 + data[point + 2] * 33.33) / 100; } } var binarize = function(data,base,th){ var ret = new Array(base.width * base.height); var getPixel = Pixel(data,base); for (var y = 0; y < base.height; y++) { for (var x = 0; x < base.width; x++) { var gray = getPixel(x, y); ret[x + y * base.width] = gray <= th ? true : false; } } return ret; } var grayscale = function(data,base) { var buff = new ArrayBuffer(base.width * base.height); var ret = new Uint8Array(buff); //var ret = new Array(base.width*base.height); var getPixel = Pixel(data,base); for (var y = 0; y < base.height; y++) { for (var x = 0; x < base.width; x++) { var gray = getPixel(x, y); ret[x + y * base.width] = gray; } } return ret; } var getMiddleBrightnessPerArea = function (image,base) { var numSqrtArea = 4; //obtain middle brightness((min + max) / 2) per area var areaWidth = Math.floor(base.width / numSqrtArea); var areaHeight = Math.floor(base.height / numSqrtArea); var minmax = new Array(numSqrtArea); for (var i = 0; i < numSqrtArea; i++) { minmax[i] = new Array(numSqrtArea); for (var i2 = 0; i2 < numSqrtArea; i2++) { minmax[i][i2] = new Array(0, 0); } } for (var ay = 0; ay < numSqrtArea; ay++) { for (var ax = 0; ax < numSqrtArea; ax++) { minmax[ax][ay][0] = 0xFF; for (var dy = 0; dy < areaHeight; dy++) { for (var dx = 0; dx < areaWidth; dx++) { var target = image[areaWidth * ax + dx + (areaHeight * ay + dy) * base.width]; if (target < minmax[ax][ay][0]) minmax[ax][ay][0] = target; if (target > minmax[ax][ay][1]) minmax[ax][ay][1] = target; } } //minmax[ax][ay][0] = (minmax[ax][ay][0] + minmax[ax][ay][1]) / 2; } } var middle = new Array(numSqrtArea); for (var i3 = 0; i3 < numSqrtArea; i3++) { middle[i3] = new Array(numSqrtArea); } for (var ay = 0; ay < numSqrtArea; ay++) { for (var ax = 0; ax < numSqrtArea; ax++) { middle[ax][ay] = Math.floor((minmax[ax][ay][0] + minmax[ax][ay][1]) / 2); //Console.out.print(middle[ax][ay] + ","); } //Console.out.println(""); } //Console.out.println(""); return middle; } var grayScaleToBitmap = function (image,base) { var middle = getMiddleBrightnessPerArea(image,base); var sqrtNumArea = middle.length; var areaWidth = Math.floor(base.width / sqrtNumArea); var areaHeight = Math.floor(base.height / sqrtNumArea); var buff = new ArrayBuffer(base.width * base.height); var bitmap = new Uint8Array(buff); //var bitmap = new Array(base.height*base.width); for (var ay = 0; ay < sqrtNumArea; ay++) { for (var ax = 0; ax < sqrtNumArea; ax++) { for (var dy = 0; dy < areaHeight; dy++) { for (var dx = 0; dx < areaWidth; dx++) { bitmap[areaWidth * ax + dx + (areaHeight * ay + dy) * base.width] = (image[areaWidth * ax + dx + (areaHeight * ay + dy) * base.width] < middle[ax][ay]) ? true : false; } } } } return bitmap; } function decode(imageDate,debugfn){ var base = { width: imageDate.width, height: imageDate.height, debugfn: debugfn } return process(imageDate.data,base) } var process = function (data,base) { // var start = new Date().getTime(); // var image = grayScaleToBitmap(grayscale(),base); // var image = binarize(128); var image = binarize(data,base,153); //转为位图; debug && base.debugfn && base.debugfn(image,base.width); // 位图转为QR矩阵 var detector = new Detector(image,base); var qRCodeMatrix = detector.detect(); if (debug, base.debugfn) { var _imgdata = []; for (var y = 0; y < qRCodeMatrix.bits.Height; y++) { for (var x = 0; x < qRCodeMatrix.bits.Width; x++) { _imgdata.push(qRCodeMatrix.bits.get_Renamed(x, y) ? true : 0) } } debugfn(_imgdata,qRCodeMatrix.bits.Width); } // 解析QR矩阵 var reader = Decoder.decode(qRCodeMatrix.bits); // console.log(reader); var data = reader.DataByte; var str = ""; for (var i = 0; i < data.length; i++) { for (var j = 0; j < data[i].length; j++) str += String.fromCharCode(data[i][j]); } // var end = new Date().getTime(); // var time = end - start; // console.log("Time:" + time + " Code: "+str); return str; } module.exports = decode;