我在 Coffeescript 中有一些奇怪的范围问题。
我无法从函数访问 _this @qr.callback
, _this 似乎没有通过。我从不更改 this.imgName 所以它不起作用的唯一原因可能是 _this 没有很好地通过。
decode:(@callback) ->
_this= this
console.log 'before',_this.imgName
@qr= new QrCode()
@qr.callback= () ->
console.log "after:", _this.imgName
@qr.decode("data:image/png;base64,#{@base64Data}")
编辑:
我试过使用
console.log 'before',@imgName
@qr= new QrCode()
@qr.callback= () =>
console.log "after:", @imgName
@qr.decode("data:image/png;base64,#{@base64Data}")
但是输出是一样的
Edit2:二维码代码:此代码来自 https://github.com/LazarSoft/jsqrcode。但是,由于 LazarSoft https://github.com/LazarSoft/jsqrcode/blob/master/src/qrcode.js的源代码不包含可以多次实例化的 QrCode 对象,我将代码转换为创建许多通过创建 QrCode 函数而不是全局对象 qrcode 来创建不同的 QrCode 实例。
QrCode= function ()
{
this.imagedata = null;
this.width = 0;
this.height = 0;
this.qrCodeSymbol = null;
this.debug = false;
this.sizeOfDataLengthInfo = [ [ 10, 9, 8, 8 ], [ 12, 11, 16, 10 ], [ 14, 13, 16, 12 ] ];
this.callback = null;
this.decode = function(src){
if(arguments.length==0)
{
var canvas_qr = document.getElementById("qr-canvas");
var context = canvas_qr.getContext('2d');
this.width = canvas_qr.width;
this.height = canvas_qr.height;
this.imagedata = context.getImageData(0, 0, this.width, this.height);
this.result = this.process(context);
if(this.callback!=null)
this.callback(this.result);
return this.result;
}
else
{
var image = new Image();
_this=this
image.onload=function(){
//var canvas_qr = document.getElementById("qr-canvas");
var canvas_qr = document.createElement('canvas');
var context = canvas_qr.getContext('2d');
var canvas_out = document.getElementById("out-canvas");
if(canvas_out!=null)
{
var outctx = canvas_out.getContext('2d');
outctx.clearRect(0, 0, 320, 240);
outctx.drawImage(image, 0, 0, 320, 240);
}
canvas_qr.width = image.width;
canvas_qr.height = image.height;
context.drawImage(image, 0, 0);
_this.width = image.width;
_this.height = image.height;
try{
_this.imagedata = context.getImageData(0, 0, image.width, image.height);
}catch(e){
_this.result = "Cross domain image reading not supported in your browser! Save it to your computer then drag and drop the file!";
if(_this.callback!=null)
_this.callback(_this.result);
return;
}
try
{
_this.result = _this.process(context);
}
catch(e)
{
// console.log('error:'+e);
_this.result = "error decoding QR Code";
}
if(_this.callback!=null)
_this.callback(_this.result);
}
image.src = src;
}
}
this.decode_utf8 = function ( s )
{
return decodeURIComponent( escape( s ) );
}
this.process = function(ctx){
var start = new Date().getTime();
var image = this.grayScaleToBitmap(this.grayscale());
//var image = this.binarize(128);
if(this.debug)
{
for (var y = 0; y < this.height; y++)
{
for (var x = 0; x < this.width; x++)
{
var point = (x * 4) + (y * this.width * 4);
this.imagedata.data[point] = image[x+y*this.width]?0:0;
this.imagedata.data[point+1] = image[x+y*this.width]?0:0;
this.imagedata.data[point+2] = image[x+y*this.width]?255:0;
}
}
ctx.putImageData(this.imagedata, 0, 0);
}
//var finderPatternInfo = new FinderPatternFinder().findFinderPattern(image);
var detector = new Detector(image,this);
var qRCodeMatrix = detector.detect();
/*for (var y = 0; y < qRCodeMatrix.bits.Height; y++)
{
for (var x = 0; x < qRCodeMatrix.bits.Width; x++)
{
var point = (x * 4*2) + (y*2 * this.width * 4);
this.imagedata.data[point] = qRCodeMatrix.bits.get_Renamed(x,y)?0:0;
this.imagedata.data[point+1] = qRCodeMatrix.bits.get_Renamed(x,y)?0:0;
this.imagedata.data[point+2] = qRCodeMatrix.bits.get_Renamed(x,y)?255:0;
}
}*/
if(this.debug)
ctx.putImageData(this.imagedata, 0, 0);
var reader = Decoder.decode(qRCodeMatrix.bits,this);
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);
return this.decode_utf8(str);
//alert("Time:" + time + " Code: "+str);
}
this.getPixel = function(x,y){
if (this.width < x) {
throw "point error";
}
if (this.height < y) {
throw "point error";
}
point = (x * 4) + (y * this.width * 4);
p = (this.imagedata.data[point]*33 + this.imagedata.data[point + 1]*34 + this.imagedata.data[point + 2]*33)/100;
return p;
}
this.binarize = function(th){
var ret = new Array(this.width*this.height);
for (var y = 0; y < this.height; y++)
{
for (var x = 0; x < this.width; x++)
{
var gray = this.getPixel(x, y);
ret[x+y*this.width] = gray<=th?true:false;
}
}
return ret;
}
this.getMiddleBrightnessPerArea=function(image)
{
var numSqrtArea = 4;
//obtain middle brightness((min + max) / 2) per area
var areaWidth = Math.floor(this.width / numSqrtArea);
var areaHeight = Math.floor(this.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)*this.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;
}
this.grayScaleToBitmap=function(grayScale)
{
var middle = this.getMiddleBrightnessPerArea(grayScale);
var sqrtNumArea = middle.length;
var areaWidth = Math.floor(this.width / sqrtNumArea);
var areaHeight = Math.floor(this.height / sqrtNumArea);
var bitmap = new Array(this.height*this.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)*this.width] = (grayScale[areaWidth * ax + dx+ (areaHeight * ay + dy)*this.width] < middle[ax][ay])?true:false;
}
}
}
}
return bitmap;
}
this.grayscale = function(){
var ret = new Array(this.width*this.height);
for (var y = 0; y < this.height; y++)
{
for (var x = 0; x < this.width; x++)
{
var gray = this.getPixel(x, y);
ret[x+y*this.width] = gray;
}
}
return ret;
}
}