前端學習--實現二維碼識別功能
概述:
最近所做的畢設專案正好與之前很火的共享單車相關,共享單車應用中很關鍵的一個部分就是掃碼用車,但我之前沒有做過相關的模組,在參考網上相關實現的教程時發現,基本上所有的二維碼識別模組都是通過客戶端來完成的很少有通過前端技術實現。令我很苦惱。
功能演示
這裡我們的網頁只是檔案只是放在本地,並使用ubuntu自帶的firefox開啟,如果使用其他瀏覽器比如谷歌可能無法彈出請求攝像頭的模態框(谷歌的安全策略不允許呼叫本地媒體)
允許攝像頭後就會開始捕捉攝像頭中的二維碼
檢視掃碼結果,我們使用草料二維碼(https://cli.im/)生成了裡面包含一個“1”字元的二維碼,經過我們的二維碼識別程式成功識別了出來,並在下面顯示出來。
程式流程圖
程式碼
index.htm(其中引用的js除了webcam.js為自己編寫的其他均為githubjsqrcode上下載的js庫)
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui" >
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<script type="text/javascript" src="https://cdn.bootcss.com/jquery/2.0.0/jquery.js"></script>
<title>scan-code</title>
<style type="text/css">
*{
padding:0;
margin:0;
}
a{
text-decoration:none;
color:#fff;
}
html{
width:100%;
height:100%;
font-size:16px;
}
body{
width:100%;
height:100%;
}
.total{
width:100%;
height:100%;
/*background:url(/static/img/bg2.jpeg) no-repeat;*/
background-size:100% 100%;
overflow: hidden;
/*background-color: #322F42;*/
}
#back_upper{
display: block;
width:4rem;
height:4rem;
margin-top: 1rem;
margin-left: 1rem;
background:url(http://img0.ph.126.net/7vVoDLyELLu5Ti2agzvxjA==/106116066320155563.png) no-repeat;
opacity:1;
}
#v{
width:320px;
height:240px;
}
#qr-canvas{
display:none;
}
#outdiv
{
}
.scanning_frame{
margin:5rem auto;
width:320px;
height:240px;
border: 3px solid #000;
position: relative
}
.infor{
width:15rem;
height: 4rem;
text-align: center;
line-height: 4rem;
background:#d81e06;
color: #fff;
border-radius: 2rem;
opacity: 0.6;
margin:0 auto;
}
#result{
width:15rem;
height:4rem;
font-size:2rem;
text-align: center;
line-height: 4rem;
margin:0 auto;
color: #d81e06;
}
/*載入動畫效果*/
.spinner {
width: 60px;
height: 60px;
position: absolute;
top:90px;
left: 130px;
/*background-color: #fff;*/
}
.double-bounce1, .double-bounce2 {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #d81e06;
opacity: 0.6;
position: absolute;
top: 0;
left: 0;
-webkit-animation: bounce 2.0s infinite ease-in-out;
animation: bounce 2.0s infinite ease-in-out;
}
.double-bounce2 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
}
@-webkit-keyframes bounce {
0%, 100% { -webkit-transform: scale(0.0) }
50% { -webkit-transform: scale(1.0) }
}
@keyframes bounce {
0%, 100% {
transform: scale(0.0);
-webkit-transform: scale(0.0);
}
50% {
transform: scale(1.0);
-webkit-transform: scale(1.0);
}
}
</style>
</head>
<body>
<div class="total">
<!-- 掃碼區域 -->
<div id="outdiv" class="scanning_frame">
<video id="v" autoplay></video>
<canvas id="qr-canvas"></canvas>
<!--載入動畫-->
<div class="spinner" id="loading">
<div class="double-bounce1"></div>
<div class="double-bounce2"></div>
</div>
</div>
<div class="infor">請掃描車上的二維碼</div>
<!-- 展示掃碼結果 -->
<div>
<p id="result"></p>
</div>
</div>
<script type="text/javascript" src="js/grid.js"></script>
<script type="text/javascript" src="js/version.js"></script>
<script type="text/javascript" src="js/detector.js"></script>
<script type="text/javascript" src="js/formatinf.js"></script>
<script type="text/javascript" src="js/errorlevel.js"></script>
<script type="text/javascript" src="js/bitmat.js"></script>
<script type="text/javascript" src="js/datablock.js"></script>
<script type="text/javascript" src="js/bmparser.js"></script>
<script type="text/javascript" src="js/datamask.js"></script>
<script type="text/javascript" src="js/rsdecoder.js"></script>
<script type="text/javascript" src="js/gf256poly.js"></script>
<script type="text/javascript" src="js/gf256.js"></script>
<script type="text/javascript" src="js/decoder.js"></script>
<script type="text/javascript" src="js/qrcode.js"></script>
<script type="text/javascript" src="js/findpat.js"></script>
<script type="text/javascript" src="js/alignpat.js"></script>
<script type="text/javascript" src="js/databr.js"></script>
<script src="js/webcam.js"></script>
<script type="text/javascript">load()</script>
</body>
</html>
webcam.js
var n = null;
var v = null;
var gCtx = null;
function captureToCanvas(){
try{
gCtx.drawImage(v,0,0);//在canvas元素中繪出video的某一幀
try{
qrcode.decode();//掃描二維碼
//console.log(qrcode.decode());//掃描成功輸出二維碼的資訊
document.getElementById('loading').style.display = "none";//隱藏掉載入動畫
}
catch(e){
console.log(e);//未掃描出二維碼,輸出錯誤資訊
setTimeout(captureToCanvas, 500);//500ms之後再重繪canvas
document.getElementById('loading').style.display = "block";
}
}
catch(e){
console.log(e);//若失敗,輸出錯誤資訊
setTimeout(captureToCanvas, 500);//500ms再重繪canvas
}
}
//初始化canvas元素,形成一個矩形框
function initCanvas(w,h){
n = navigator;
v = document.getElementById("v");
var gCanvas = document.getElementById("qr-canvas");
gCanvas.style.width = w + "px";
gCanvas.style.height = h + "px";
gCanvas.width = w;
gCanvas.height = h;
gCtx = gCanvas.getContext("2d");
gCtx.clearRect(0, 0, w, h);
}
function setwebcam(){
var options = true;
if(navigator.mediaDevices && navigator.mediaDevices.enumerateDevices)
{
try{
navigator.mediaDevices.enumerateDevices().then(function(devices) {
devices.forEach(function(device) {
if (device.kind === 'videoinput') {
if(device.label.toLowerCase().search("back") >-1)
options={'deviceId': {'exact':device.deviceId}, 'facingMode':'environment'} ;
}
console.log(device.kind + ": " + device.label +" id = " + device.deviceId);
});
setwebcam2(options);
});
}
catch(e)
{
console.log(e);
}
}
else{
console.log("no navigator.mediaDevices.enumerateDevices" );
}
}
function setwebcam2(options){
var p = n.mediaDevices.getUserMedia({video: options, audio: false});
p.then(success, error);
// setTimeout(captureToCanvas, 500);
}
function success(stream){
v.srcObject = stream;
setTimeout(captureToCanvas(), 500);
}
function error(error){
console.log(error);
}
function load(){
initCanvas(800,600);
qrcode.callback = read;
setwebcam();
}
function read(a){
document.getElementById("result").innerHTML = a.toString();
console.log("qrcode info:"+a);//輸出掃描後的資訊
}
相關推薦
前端學習--實現二維碼識別功能
概述: 最近所做的畢設專案正好與之前很火的共享單車相關,共享單車應用中很關鍵的一個部分就是掃碼用車,但我之前沒有做過相關的模組,在參考網上相關實現的教程時發現,基本上所有的二維碼識別模組都是通過客戶端來完成的很少有通過前端技術實現。令我很苦惱。
Android實現二維碼掃描功能(二)-ZXing個性化與近距離識別優化
簡介 本篇我們對掃碼介面進行優化,並對ZXing近距離無法識別的問題做出優化。 個性化定製 每個APP都有自己的表現形式,實現個性化掃碼介面定製,主要有兩個地方: activity_scanner.xml介面檔案 com.google.zxin
Android實現二維碼掃描功能(三)-閃光燈控制
簡介 本篇我們對光線暗淡情況下閃光燈的使用做出介紹。 效果 晚上測試時: 開燈後: 未開燈: 實現步驟 1、在activity_scanner.xml介面上加上閃光燈開關按鈕。可以是Button、Checkbox等控制元件。
Android開發之Zbar實現二維碼掃描功能
前言: 在寫這篇文章之前已經寫過兩篇關於二維碼功能的文章,有興趣的可以看看——》文章1:Android開發之利用ZXing庫實現二維碼的掃描;文章2:Android開發之利用ZXing庫實現二維碼的生成,這兩篇文章中使用到的二維碼生成庫是ZXing,在本篇
Android開發技巧——五分鐘實現二維碼識別
/** * This activity opens the camera and does the actual scanning on a background * thread. It draws a viewfinder to help the user place the barcode cor
ios-實現二維碼掃描功能
在此就簡單的介紹下二維碼掃描功能的實現把 首先先說下思路,我們需要去配置的就是 1、輸入裝置(用來獲取外界資訊),輸入裝置有攝像頭、麥克風、鍵盤 2、輸出裝置(將收集到的資訊進行解析去獲取收到的內容) 3、會話的session(用來連線輸入和輸出的裝置),不然的
iOS使用ZBar實現二維碼掃描以及實現識別相簿中二維碼圖片功能
使用zbar呼叫相機掃碼程式碼: //開啟相機 - (void) init_camera { self.navigationController.navigationBarHidden=YES; [commonaddNavigationAddToView:
Android 二維碼開發功能實現(四)------基於Zxing實現編碼功能(生成二維碼,一維碼等)
Android 二維碼開發功能實現(四)------基於Zxing實現編碼功能(生成二維碼,一維碼等) 前言 關於Google的開源庫Zxing,前面也寫了幾遍文章進行介紹.我們先簡單的回顧一下! Android 二維碼的掃碼功能實現(一) 這篇文章主要介紹了,Zxi
Android Zxing實現掃描二維碼條形碼功能仿微信整合閃光燈生成二維碼
最近在做android專案需要用到二維碼條形碼掃描功能,我用的是Eclipse網上原始碼大多是GitHup上的Android studio版本的所以我改了一版整合到專案中去。 效果圖: 左邊版本的掃碼框是自定義的。右邊版本的掃碼框和掃描線是圖片因為太醜所以最終換成左邊
Java實現生成二維碼圖片功能
import cn.api.commons.commons.util.MatrixToImageWriter; import java.io.File; import java.io.FileOutputStream; import java.io.InputStr
OpenCV和Zbar兩個Python模組實現二維碼和條形碼識別
在我們的日常生活中,處處可見條形碼和二維碼。 在以前,我們去逛書店時,或者你現在隨手拿起你身邊的一本書,你肯定能看到書本的封頁後面印有一排黑色線條組成的標籤,也就是條形碼;你去你們學校的自助機上借書還書時識別的也是條形碼;哦,對了,你還記得每次大型考試答題卡上都會貼上監考老師分發給你的那個標籤嗎?還是條形碼
OpenCV和Zbar兩個Python模塊實現二維碼和條形碼識別
組成 cimage 老師 font key ans 部分 平時 ubuntu 在我們的日常生活中,處處可見條形碼和二維碼。 在以前,我們去逛書店時,或者你現在隨手拿起你身邊的一本書,你肯定能看到書本的封頁後面印有一排黑色線條組成的標簽,也就是條形碼;你去你們學校的自助機上借
halcon學習筆記(13)——二維碼識別及簡單定位
前面說了利用halcon進行二維碼的識別,這次進行二維碼識別及方向定位,雖然二維碼本身也有定位和方向性,但是我沒有在halcon運算元裡找到這個函式或調出這個引數的方法;不過可以通過在二維碼附近新增mark圖形來進行角度和方向識別,這樣在AGV小車應用中就可作為地標識別程式
Android 二維碼開發功能實現(五)-----對zxing進行優化,提高掃碼速度與精確度
對zxing進行優化的思考 前言 對於Google 的開源框架Zxing庫的使用介紹,前面也通過幾篇文章進行解讀. Android 二維碼的掃碼功能實現(一) Android 基於Zxing的掃碼功能實現(二) Android 基於Zxing掃碼實現(三)
html5二維碼掃描功能實現
html5中可以使用二維碼掃描,也可以從相簿中選擇二維碼識別,程式碼如下 var ws = null, wo = null; var scan = null, domr
在iOS上實現二維碼功能、二維碼、條形碼、swift 二維碼
iOS 識別二維碼、識別條形碼等 二維碼生成、條形碼生成等 掃碼背景色、掃碼框顏色、掃碼框4個角的顏色均可通過引數修改 動畫效果:線條上下移動、網格形式移動、中間線條不移動(一般掃碼條形碼的效果) 掃碼成功後,獲取當前圖片 模仿QQ掃碼介面 支付寶掃碼框效
Android 基於zxing的二維碼掃描功能的簡單實現及優化
由於專案中需要接入一下簡單的二維碼掃描功能,最終使用 zxing 來實現,把官方例子中的部分程式碼摘除出來做了簡單的封裝,並進行了一些優化。這裡簡單做一個記錄。 掃描二維碼 Android 中關於二維碼掃描的庫有很多,但是歸根到底無外乎下面這幾種
Android中Webview與原生介面互動及二維碼掃描功能實現
最近專案中有一個新的需求,大致是這樣的:APP中通過WebView展示一個第三方的HTML5介面,使用者可以在HTML5介面中呼叫Android攝像頭進行二維碼掃描,並將掃描結果顯示在HTML5介面。這顯然涉及到了Android原生與WebView之前的傳值
sencha-touch下藉助phoneGap實現拍照,二維碼的功能
1.配置 在android專案中拷入相應的檔案,layout+raw+values+xml AndroidMainfest.xml中註冊 <activity android:name="com.Plugin.scan.CaptureActivity" android
phonegap的二維碼掃描功能的實現
首先簡單的介紹下DOS環境下phonegap專案的結構,如下圖: 如果大家的專案結構和上圖中專案結構一樣,就可以按照下面的步驟來實現掃描二維碼的功能了,不一樣的下面的步驟也可以提供一定的參考。 ####################START#######