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.
QRCode-decode/src/QRDecode.js

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;