1. 程式人生 > >基於html5、JS實現的二維碼掃碼

基於html5、JS實現的二維碼掃碼

原理:調出攝像頭,拍照儲存到畫布,定時傳送到解析函式

說明:解析函式是後臺c# .net MVC 實現的,解析函式用到的二維碼解析API依賴於第三方二維碼庫google zxing , 因此需要先引用類庫:zxing.dll、zxing.presentation.dll,如果你在網上找到可以用JS解析的麻煩留言相告,因為用JS解析是最好的方法,不用每次定時的發出http請求,也可以不用引入google zxing,不用c# .net MVC後臺去解析,這樣是最好的,但目前在網上找到的二維碼掃描多數是用flash實現的,flash這種東西適用於PC端,卻無法再android, iphone等移動終端上正常顯示,即使正常,還要使用者安裝adobe flash外掛才可以掃描,即使可以掃描,記憶體代價也比較高,如果你瞭解二維碼原理,並想自己翻譯這個解析演算法,可以參考以下網址:

clouda+ (百度的JS端能力,目前已經有二維碼掃描控制元件,可以分析它的原理):http://clouda.baidu.com/

前端程式碼(QRcodeDecode.cshtml):

<style>#video {display: block;margin:1em auto;width:180px;height:180px;}</style>  
<video id="video" autoplay></video>
<script>
    window.addEventListener("DOMContentLoaded", function () {
        var video = document.getElementById("video"), canvas, context;
        try {
            canvas = document.createElement("canvas");
            context = canvas.getContext("2d");
        } catch (e) { alert("not support canvas!"); return; }
        navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;


        if (navigator.getUserMedia)
            navigator.getUserMedia(
                { "video": true },
                function (stream) {
                    if (video.mozSrcObject !== undefined)video.mozSrcObject = stream;
                    else video.src = ((window.URL || window.webkitURL || window.mozURL || window.msURL) && window.URL.createObjectURL(stream)) || stream;               
                    video.play();
                },
                function (error) {
                    //if(error.PERMISSION_DENIED)console.log("使用者拒絕了瀏覽器請求媒體的許可權",error.code);
                    //if(error.NOT_SUPPORTED_ERROR)console.log("當前瀏覽器不支援拍照功能",error.code);
                    //if(error.MANDATORY_UNSATISFIED_ERROR)console.log("指定的媒體型別未接收到媒體流",error.code);
                    alert("Video capture error: " + error.code);
                }
            );
        else alert("Native device media streaming (getUserMedia) not supported in this browser");
       


        setInterval(function () {
            context.drawImage(video, 0, 0, canvas.width = video.videoWidth, canvas.height = video.videoHeight);
            $.post('/Home/QRcodeDecode', { "img": canvas.toDataURL().substr(22) }, function (data, status) {
                if (status == "success" && data != "no")location.href = "/Home/Result/" + data;               
            }, "text");
        }, 500);


    }, false);
 </script> 


後臺程式碼(HomeController.cs):

using System;
using System.Drawing;
using System.IO;
using System.Web.Mvc;
using ZXing;


namespace WebFrame.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult QRcodeDecode(){ return View();}


        [HttpPost]
        public ActionResult QRcodeDecode(FormCollection form)
        {
            try{
                byte[] imgBytes = Convert.FromBase64String(form["img"]);        
                Stream stream = new MemoryStream(imgBytes);
                Result result = new BarcodeReader().Decode(new Bitmap(stream));
                return Content(Uri.EscapeDataString(result.Text));
            }catch{ return Content("no");}
        }


        public ActionResult Result(string id) { return View(); }
    }
}

以下是在android UC瀏覽器上看到的效果,開啟測試頁面,掃描帶"hello Kitty !"的二維碼

(帶"hello Kitty !"的二維碼):


識別成功效果圖



附上Demo下載地址:html5二維碼掃描   (含zxing.dll、zxing.presentation.dll、完整示例專案)

作為辛苦勞動成果,設定了3分滴下載小費,沒分的筒鞋想辦法獲取積分,好的社群需要大家一同建設,杜絕伸手黨

注:部分新手下載後不會使用,在此特別說明下,本工程使用VS2013或VS2012開啟,執行一般能成功,若提醒錯誤的,提醒哪行出錯就註釋掉哪行就可以了,然後這個站點佈署到IIS上,用手機訪問入口地址:“/Home/QRcodeDecode”,此時就會顯示呼叫手機裝置授權了。

Android、IOS 內建瀏覽器上展示未測試,估計也是沒問題滴,不過一般Android、IOS都用自己API實現掃碼的,之所以還用h5,就是給瀏覽器掃碼使用的,如果你有更好的方法或其它問題可以留言,大家共同探討,共同學習。