如何將一個URL轉爲二維碼並配上文字說明再將其轉爲圖片下載下來

最近公司業務有一個需求,在頁面上須要將一個URL轉爲二維碼並配上文字說明,並提供一個下載按鈕,能夠下載帶有文字說明的二維碼圖片。

若是說只要一個二維碼圖片,Github上的qrcodejs庫就能幫咱們實現;javascript

可是若是再加上文字說明,狀況就變得有那麼一絲複雜。css

王二以前嘗試過直接在canvas裏繪畫文字,可是canvas裏文字不會換行,雖然能夠經過js控制每行文字的數量來換行,可是文字有寬有窄,終究不是一個好的解決方案;html

而後又上網找解決方案,而後據說用svg能夠直接將一個div整個畫出來。王二也嘗試了,svg確實能夠將div整個畫出來,再導入到canvas裏。這時候二維碼和文字說明都在一張canvas裏,並且文字實際上能夠用css的樣式來控制。可是在最後一步,將canvas轉換爲base64再導出圖片的時候栽了跟頭,在canvas裏用svg畫出來的部分最後轉爲圖片的時候不會呈現,這條思路彷佛又走不通了。java

而後又上網找解決方案,最後在Github發現了html2canvas這個神奇的庫,它能夠將一個div繪畫成canvas,那麼思路也隨之而來了。git

王二寫了以下的一串html代碼,並對 qrcodehtml2canvas 進行了一個簡單的封裝,如下代碼能夠直接運行,有興趣能夠直接拷貝到本地看看運行效果:github

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8"/>
</head>
<body>
<div id="QRcode"></div>
<a class="QR-download" href="#" download>下載</a>
<script src="http://www.wangyulue.com/assets/js/qrcode.js"></script>
<script src="http://www.wangyulue.com/assets/js/html2canvas.min.js"></script>
<script> /** * 輸出一個帶有文字說明的二維碼。 * * @param {Object} obj 相關配置, * obj = { dom : "QRcode", // url : "http://www.wangyulue.com", //二維碼網址 text : ["王玉略的我的網站","Stay Hungry, Stay Foolish."], //二維碼的文字說明 pic_size : 300, // 圖片的尺寸大小 font_size : 16, //說明文字的字體大小 } * 回調函數中返回一個base64形式的圖片,以便在回調中注入到<a>標籤中下載使用 * */ function getQRcodeImg(obj,fn){ var url = obj.url, size = obj.pic_size || 256; font_size = obj.font_size || 18; dom = document.getElementById(obj.dom); dom.innerHTML = generateHTML(obj.text,size,font_size); var $qrcode = dom.getElementsByClassName("QR-qrcode")[0], $main = dom.getElementsByClassName("QR-main")[0]; new QRCode($qrcode, { text: url, width: size, height: size, }); html2canvas($main).then(function(canvas) { var base64 = concatCanvas(dom,$qrcode.getElementsByTagName("canvas")[0],canvas,20); fn && fn(base64); }); /** * 根據配置拼湊要處理的html代碼 * * @param {Array} arr 要添加的文字,以數組傳入 * */ function generateHTML(arr,size,font_size){ var out = "",temp = ""; arr.forEach(function(item){ temp += "<div style='text-align:center;font-size:" +font_size+ "px;'>"+ item +"</div>" ; }) out = "<div style='position:absolute;opacity:0;'>" + "<div class='QR-main' style='width: " +size+ "px;'>" + temp + "</div>" + "</div>" + "<div class='QR-qrcode' style='display:none;'></div>"; return out ; } /** * 將兩個canvas合併在一塊兒 * * @param {Object} dom canvas要添加的dom對象 * @param {Object} canvas1 第一個canvas * @param {Object} canvas2 第二個canvas * @param {Number} padding 圖片的padding,默認20 * @return {String} 返回base64字符串 * */ function concatCanvas(dom,canvas1,canvas2,padding){ var c1h = canvas1.height, c1w = canvas1.width, // c2h = canvas2.height,  // c2w = canvas2.width, /* 說明:將以上兩行代碼改成如下兩行代碼; * 緣由:以上兩行代碼在window下顯示是好的,可是放到Mac下顯示會出一些問題, * 仔細發現是在Mac下,html2canvas的API返回的canvas不符合預期,在MAC環境canvas返回以下: * html2canvas($main).then(function(canvas) { * console.log(canvas); //<canvas width="600" height="88" style="width: 300px; height: 44px;"></canvas> * }); * 能夠看到看到canvas的width和height值和其style裏的width和height的值有所不一樣, * 因而採用如下的方法來得到canvas的寬度和高度 * 王二認爲出現以上問題多是由於分辨率的問題 */ c2h = Number(canvas2.style.height.slice(0,-2)); c2w = Number(canvas2.style.width.slice(0,-2)); canvas = document.createElement("canvas"); padding = padding || 20 ; /** 根據二維碼、文字兩個canvas,再加上padding計算出新的canvas的寬度和高度 **/ canvas.height = c1h + c2h + 2.5 * padding ; canvas.width = Math.max(c1w,c2w) + 2 * padding ; /** end **/ dom.appendChild(canvas); /** 將canvas畫上白色背景 **/ context = canvas.getContext("2d"); context.fillStyle ="white"; context.fillRect(0,0,canvas.width,canvas.height); /** end **/ /** 將二維碼、文字兩個canvas繪畫到一個canvas裏 **/ context.drawImage(canvas1, padding, padding, c1w ,c1h); context.drawImage(canvas2, padding, 1.5 * padding+c1h, c2w ,c2h); /** end **/ /** 返回base64,用於注入到a標籤裏以便下載 **/ return canvas.toDataURL('image/jpeg',1); /** end **/ } } var obj = { dom : "QRcode", url : "http://www.wangyulue.com", text : ["王玉略的我的網站","Stay Hungry, Stay Foolish."], pic_size : 300, font_size : 16, } getQRcodeImg(obj,function(base64){ document.getElementsByClassName("QR-download")[0].href = base64 ; }); </script>
</body>
</html>
複製代碼

下載後的圖片就像下面這樣:canvas

Alt text

對於很長的文字,它也能很完美的換行,而且圖片的高度自適應,就像下面這樣:數組

Alt text

這樣來看,這個需求算是被完美解決了。app

原文發表於 王玉略的我的網站dom

相關文章
相關標籤/搜索