|
|
- /*
- Copyright 2011 Lazar Laszlo (lazarsoft@gmail.com, www.lazarsoft.info)
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-
- var qrcode = {};
- qrcode.imagedata = null;
- qrcode.width = 0;
- qrcode.height = 0;
- qrcode.qrCodeSymbol = null;
- qrcode.debug = false;
- qrcode.maxImgSize = 1024*1024;
-
- qrcode.sizeOfDataLengthInfo = [ [ 10, 9, 8, 8 ], [ 12, 11, 16, 10 ], [ 14, 13, 16, 12 ] ];
-
- qrcode.callback = null;
-
- qrcode.vidSuccess = function (stream)
- {
- qrcode.localstream = stream;
- if(qrcode.webkit)
- qrcode.video.src = window.webkitURL.createObjectURL(stream);
- else
- if(qrcode.moz)
- {
- qrcode.video.mozSrcObject = stream;
- qrcode.video.play();
- }
- else
- qrcode.video.src = stream;
-
- qrcode.gUM=true;
-
- qrcode.canvas_qr2 = document.createElement('canvas');
- qrcode.canvas_qr2.id = "qr-canvas";
- qrcode.qrcontext2 = qrcode.canvas_qr2.getContext('2d');
- qrcode.canvas_qr2.width = qrcode.video.videoWidth;
- qrcode.canvas_qr2.height = qrcode.video.videoHeight;
- setTimeout(qrcode.captureToCanvas, 500);
- }
-
- qrcode.vidError = function(error)
- {
- qrcode.gUM=false;
- return;
- }
-
- qrcode.captureToCanvas = function()
- {
- if(qrcode.gUM)
- {
- try{
- if(qrcode.video.videoWidth == 0)
- {
- setTimeout(qrcode.captureToCanvas, 500);
- return;
- }
- else
- {
- qrcode.canvas_qr2.width = qrcode.video.videoWidth;
- qrcode.canvas_qr2.height = qrcode.video.videoHeight;
- }
- qrcode.qrcontext2.drawImage(qrcode.video,0,0);
- try{
- qrcode.decode();
- }
- catch(e){
- console.log(e);
- setTimeout(qrcode.captureToCanvas, 500);
- };
- }
- catch(e){
- console.log(e);
- setTimeout(qrcode.captureToCanvas, 500);
- };
- }
- }
-
- qrcode.setWebcam = function(videoId)
- {
- var n=navigator;
- qrcode.video=document.getElementById(videoId);
-
- var options = true;
- if(navigator.mediaDevices && navigator.mediaDevices.enumerateDevices)
- {
- try{
- navigator.mediaDevices.enumerateDevices()
- .then(function(devices) {
- devices.forEach(function(device) {
- console.log("deb1");
- if (device.kind === 'videoinput') {
- if(device.label.toLowerCase().search("back") >-1)
- options=[{'sourceId': device.deviceId}] ;
- }
- console.log(device.kind + ": " + device.label +
- " id = " + device.deviceId);
- });
- })
-
- }
- catch(e)
- {
- console.log(e);
- }
- }
- else{
- console.log("no navigator.mediaDevices.enumerateDevices" );
- }
-
- if(n.getUserMedia)
- n.getUserMedia({video: options, audio: false}, qrcode.vidSuccess, qrcode.vidError);
- else
- if(n.webkitGetUserMedia)
- {
- qrcode.webkit=true;
- n.webkitGetUserMedia({video:options, audio: false}, qrcode.vidSuccess, qrcode.vidError);
- }
- else
- if(n.mozGetUserMedia)
- {
- qrcode.moz=true;
- n.mozGetUserMedia({video: options, audio: false}, qrcode.vidSuccess, qrcode.vidError);
- }
- }
-
- qrcode.decode = function(src){
-
- if(arguments.length==0)
- {
- if(qrcode.canvas_qr2)
- {
- var canvas_qr = qrcode.canvas_qr2;
- var context = qrcode.qrcontext2;
- }
- else
- {
- var canvas_qr = document.getElementById("qr-canvas");
- var context = canvas_qr.getContext('2d');
- }
- qrcode.width = canvas_qr.width;
- qrcode.height = canvas_qr.height;
- qrcode.imagedata = context.getImageData(0, 0, qrcode.width, qrcode.height);
- qrcode.result = qrcode.process(context);
- if(qrcode.callback!=null)
- qrcode.callback(qrcode.result);
- return qrcode.result;
- }
- else
- {
- var image = new Image();
- image.crossOrigin = "Anonymous";
- image.onload=function(){
- //var canvas_qr = document.getElementById("qr-canvas");
- 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);
- }
-
- var canvas_qr = document.createElement('canvas');
- var context = canvas_qr.getContext('2d');
- var nheight = image.height;
- var nwidth = image.width;
- if(image.width*image.height>qrcode.maxImgSize)
- {
- var ir = image.width / image.height;
- nheight = Math.sqrt(qrcode.maxImgSize/ir);
- nwidth=ir*nheight;
- }
-
- canvas_qr.width = nwidth;
- canvas_qr.height = nheight;
-
- context.drawImage(image, 0, 0, canvas_qr.width, canvas_qr.height );
- qrcode.width = canvas_qr.width;
- qrcode.height = canvas_qr.height;
- try{
- qrcode.imagedata = context.getImageData(0, 0, canvas_qr.width, canvas_qr.height);
- }catch(e){
- qrcode.result = "Cross domain image reading not supported in your browser! Save it to your computer then drag and drop the file!";
- if(qrcode.callback!=null)
- qrcode.callback(qrcode.result);
- return;
- }
-
- try
- {
- qrcode.result = qrcode.process(context);
- }
- catch(e)
- {
- console.log(e);
- qrcode.result = "error decoding QR Code";
- }
- if(qrcode.callback!=null)
- qrcode.callback(qrcode.result);
- }
- image.onerror = function ()
- {
- if(qrcode.callback!=null)
- qrcode.callback("Failed to load the image");
- }
- image.src = src;
- }
- }
-
- qrcode.isUrl = function(s)
- {
- var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
- return regexp.test(s);
- }
-
- qrcode.decode_url = function (s)
- {
- var escaped = "";
- try{
- escaped = escape( s );
- }
- catch(e)
- {
- console.log(e);
- escaped = s;
- }
- var ret = "";
- try{
- ret = decodeURIComponent( escaped );
- }
- catch(e)
- {
- console.log(e);
- ret = escaped;
- }
- return ret;
- }
-
- qrcode.decode_utf8 = function ( s )
- {
- if(qrcode.isUrl(s))
- return qrcode.decode_url(s);
- else
- return s;
- }
-
- qrcode.process = function(ctx){
-
- var start = new Date().getTime();
-
- var image = qrcode.grayScaleToBitmap(qrcode.grayscale());
- //var image = qrcode.binarize(128);
-
- if(qrcode.debug)
- {
- for (var y = 0; y < qrcode.height; y++)
- {
- for (var x = 0; x < qrcode.width; x++)
- {
- var point = (x * 4) + (y * qrcode.width * 4);
- qrcode.imagedata.data[point] = image[x+y*qrcode.width]?0:0;
- qrcode.imagedata.data[point+1] = image[x+y*qrcode.width]?0:0;
- qrcode.imagedata.data[point+2] = image[x+y*qrcode.width]?255:0;
- }
- }
- ctx.putImageData(qrcode.imagedata, 0, 0);
- }
-
- //var finderPatternInfo = new FinderPatternFinder().findFinderPattern(image);
-
- var detector = new Detector(image);
-
- var qRCodeMatrix = detector.detect();
-
- if(qrcode.debug)
- {
- 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 * qrcode.width * 4);
- qrcode.imagedata.data[point] = qRCodeMatrix.bits.get_Renamed(x,y)?0:0;
- qrcode.imagedata.data[point+1] = qRCodeMatrix.bits.get_Renamed(x,y)?0:0;
- qrcode.imagedata.data[point+2] = qRCodeMatrix.bits.get_Renamed(x,y)?255:0;
- }
- }
- ctx.putImageData(qrcode.imagedata, 0, 0);
- }
-
-
- var reader = Decoder.decode(qRCodeMatrix.bits);
- 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 qrcode.decode_utf8(str);
- //alert("Time:" + time + " Code: "+str);
- }
-
- qrcode.getPixel = function(x,y){
- if (qrcode.width < x) {
- throw "point error";
- }
- if (qrcode.height < y) {
- throw "point error";
- }
- var point = (x * 4) + (y * qrcode.width * 4);
- var p = (qrcode.imagedata.data[point]*33 + qrcode.imagedata.data[point + 1]*34 + qrcode.imagedata.data[point + 2]*33)/100;
- return p;
- }
-
- qrcode.binarize = function(th){
- var ret = new Array(qrcode.width*qrcode.height);
- for (var y = 0; y < qrcode.height; y++)
- {
- for (var x = 0; x < qrcode.width; x++)
- {
- var gray = qrcode.getPixel(x, y);
-
- ret[x+y*qrcode.width] = gray<=th?true:false;
- }
- }
- return ret;
- }
-
- qrcode.getMiddleBrightnessPerArea=function(image)
- {
- var numSqrtArea = 4;
- //obtain middle brightness((min + max) / 2) per area
- var areaWidth = Math.floor(qrcode.width / numSqrtArea);
- var areaHeight = Math.floor(qrcode.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)*qrcode.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;
- }
-
- qrcode.grayScaleToBitmap=function(grayScale)
- {
- var middle = qrcode.getMiddleBrightnessPerArea(grayScale);
- var sqrtNumArea = middle.length;
- var areaWidth = Math.floor(qrcode.width / sqrtNumArea);
- var areaHeight = Math.floor(qrcode.height / sqrtNumArea);
-
- var buff = new ArrayBuffer(qrcode.width*qrcode.height);
- var bitmap = new Uint8Array(buff);
-
- //var bitmap = new Array(qrcode.height*qrcode.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)*qrcode.width] = (grayScale[areaWidth * ax + dx+ (areaHeight * ay + dy)*qrcode.width] < middle[ax][ay])?true:false;
- }
- }
- }
- }
- return bitmap;
- }
-
- qrcode.grayscale = function()
- {
- var buff = new ArrayBuffer(qrcode.width*qrcode.height);
- var ret = new Uint8Array(buff);
- //var ret = new Array(qrcode.width*qrcode.height);
-
- for (var y = 0; y < qrcode.height; y++)
- {
- for (var x = 0; x < qrcode.width; x++)
- {
- var gray = qrcode.getPixel(x, y);
-
- ret[x+y*qrcode.width] = gray;
- }
- }
- return ret;
- }
-
-
-
-
- function URShift( number, bits)
- {
- if (number >= 0)
- return number >> bits;
- else
- return (number >> bits) + (2 << ~bits);
- }
-
|