收藏 | 點贊
現(xiàn)在二維碼越來越流行啦,支付掃二維碼,關(guān)注掃二維碼,抽獎掃二維碼......,總之,二維碼無處不在,那怎么制作一個二維碼呢?我們今天就此問題一起來討論一下
一、什么是二維碼
首先我們來了解一下,什么是二維碼?百度百科上是這樣解釋的:二維條碼/二維碼(2-dimensional bar code)是用某種特定的幾何圖形按一定規(guī)律在平面(二維方向上)分布的黑白相間的圖形記錄數(shù)據(jù)符號信息的;在代碼編制上巧妙地利用構(gòu)成計算機(jī)內(nèi)部邏輯基礎(chǔ)的“0”、“1”比特流的概念,使用若干個與二進(jìn)制相對應(yīng)的幾何形體來表示文字?jǐn)?shù)值信息,通過圖象輸入設(shè)備或光電掃描設(shè)備自動識讀以實現(xiàn)信息自動處理:它具有條碼技術(shù)的一些共性:每種碼制有其特定的字符集;每個字符占有一定的寬度;具有一定的校驗功能等。同時還具有對不同行的信息自動識別功能、及處理圖形旋轉(zhuǎn)變化點。
二、具體實現(xiàn)
那怎么來實現(xiàn)制作出一個二維碼呢?有很多小伙伴是在服務(wù)器端生成二維碼,作為前端控,小五今天就和大家磨叨一下怎么在前端生成二維碼。其實小五還是走了捷徑,采用了一個二維碼插件jquery-qrcode,可以從https://github.com/jeromeetienne/jquery-qrcode 獲取,這是一個免費(fèi)開源的插件。qrcode.js 是實現(xiàn)二維碼數(shù)據(jù)計算的核心類,jquery.qrcode.js 是把它用jquery方式封裝起來的,用它來實現(xiàn)圖形渲染,其實就是畫圖(支持canvas和table兩種方式)
1、支持的功能主要有:
text : " http://www.h5-share.com/ " //設(shè)置二維碼內(nèi)容 render : "canvas",//設(shè)置渲染方式 (有兩種方式 table和canvas,默認(rèn)是canvas) width : 256, //設(shè)置寬度 height : 256, //設(shè)置高度 typeNumber : -1, //計算模式 correctLevel : 0,//糾錯等級 background : "#ffffff",//背景顏色 foreground : "#000000" //前景顏色
2、使用方式非常簡單
需要引入jQuery 和 jquery.qrcode.js
①$('#qr_container').qrcode({render:"table",height:180,width:180,correctLevel:0,text:$('#qr_text').val()});
②$('#qr_container').qrcode({render:"canvas",height:180,width:180,correctLevel:0,text:$('#qr_text').val()});
當(dāng)你分別執(zhí)行了上面的例子,就可以看到,二維碼使用canvas畫出來,在網(wǎng)頁上輸出一個canvas節(jié)點。但是用到table的話,我們會發(fā)現(xiàn)二維碼實際是使用table表格把每一個二維碼的點畫出來,這就導(dǎo)致網(wǎng)頁上的Dom元素會特別多。
選擇canvas,ie8一下的瀏覽器就沒辦法支持。選擇table吧,一切看起來都很美好。但在實際使用的過程中,當(dāng)二維碼的內(nèi)容較多時,二維碼的尺寸較小時(比如120px * 120 px),用table來渲染,會發(fā)現(xiàn)生成的二維碼很難識別。
作為移動端開發(fā)者,現(xiàn)代的智能機(jī)基本上都支持canvas,那我們就用canvas吧,但是新的問題又來了,就是jquery.qrcode.js默認(rèn)不支持中文。
這跟js的機(jī)制有關(guān)系,jquery-qrcode這個庫是采用 charCodeAt() 這個方式進(jìn)行編碼轉(zhuǎn)換的,而這個方法默認(rèn)會獲取它的 Unicode 編碼,一般的解碼器都是采用UTF-8, ISO-8859-1等方式,英文是沒有問題,如果是中文,一般情況下Unicode是UTF-16實現(xiàn),長度2位,而UTF-8編碼是3位,這樣二維碼的編解碼就不匹配了。
解決方式當(dāng)然是,在二維碼編碼前把字符串轉(zhuǎn)換成UTF-8,具體代碼如下:
function utf16to8(str) { var out, i, len, c; out = ""; len = str.length; for(i = 0; i < len; i++) { c = str.charCodeAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { out += str.charAt(i); } else if (c > 0x07FF) { out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F)); out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F)); out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); } else { out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F)); out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); } } return out; }
現(xiàn)在中文生成二維碼解決了,但是?。?!你生成的二維碼在canvas里,怎么保存在本地呢?很簡單,把canvas里的信息轉(zhuǎn)換成img圖片就行了。
// 從canvas提取圖片image function convertCanvasToImage(canvas){ //新Image對象,可以理解為DOM; var image = new Image(); //canvas.toDataURL返回的是一串Base64編碼的URL image.src = canvas.toDataURL("image/png"); return image; }
三、完整示例:
html:
生成簡易二維碼
js:
$(document).ready(function(){ // 點擊生成二維碼 $('#qr_btn').click(function(){ /*如果已生成過二維碼,則刪除二維碼img圖片和canvas,重新生成;反之,則直接生成二維碼*/ if($('#imgDiv:has(img)').length!=0){ $('#imgDiv img').remove(); $('canvas').remove(); createQr(); }else{ createQr(); } }); // 生成二維碼 function createQr(){ document.createElement('canvas').getContext('2d'); var valText = $('#qr_text').val(); // 采用正則表達(dá)式判斷輸入的內(nèi)容是否是中文 var reg=/^[\u0391-\uFFE5]+$/; if(valText!=""&&!reg.test(valText)){ // 如果不是中文,直接將輸入的內(nèi)容轉(zhuǎn)換成二維碼 $('#qr_container').qrcode({render:"canvas",height:180, width:180,correctLevel:0,text:valText}); }else{ // 如果是中文,直接將輸入的內(nèi)容字符串轉(zhuǎn)換成UTF-8,然后再轉(zhuǎn)換成二維碼 $('#qr_container').qrcode({render:"canvas",height:180, width:180,correctLevel:0,text:utf16to8(valText)}); } //獲取網(wǎng)頁中的canvas對象 var mycanvas1=document.getElementsByTagName('canvas')[0]; //將轉(zhuǎn)換后的img標(biāo)簽插入到html中 var img = convertCanvasToImage(mycanvas1); $('#imgDiv').append(img);//imgDiv表示你要插入的容器id } // 字符編碼 function utf16to8(str) { var out, i, len, c; out = ""; len = str.length; for(i = 0; i < len; i++) { c = str.charCodeAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { out += str.charAt(i); } else if (c > 0x07FF) { out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F)); out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F)); out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); } else { out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F)); out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); } } return out; } //從canvas中提取圖片image function convertCanvasToImage(canvas) { //新Image對象,可以理解為DOM var image = new Image(); // canvas.toDataURL 返回的是一串Base64編碼的URL // 指定格式PNG image.src = canvas.toDataURL("image/png"); return image; } });
0 條評論