You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
4.9 KiB
JavaScript
156 lines
4.9 KiB
JavaScript
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; |