將canvas 轉圖片 以及 將 圖片轉成 canvas的方法
1. 圖片轉到畫布上
// Converts image to canvas; returns new canvas element function convertImageToCanvas(image) { var canvas = document.createElement("canvas"); canvas.width = image.width; canvas.height = image.height; canvas.getContext("2d").drawImage(image, 0, 0); return canvas; } // (image, 0, 0); 其中0,0表示canvas的坐標點
2. 畫布轉成圖片
// Converts canvas to an image function convertCanvasToImage(canvas) { var image = new Image(); image.src = canvas.toDataURL("image/png"); return image; } // "image/png"表示canvas轉成的圖片類型,默認是png,可以改成"image/jpeg"
3. base64圖片下載到本地(android另說)
/** * 下載Base64到本地 1. trident內核都不可以(IE,獵豹) 2. chrome, opera 等使用blink內核 可以(但是chrome好像還是webkit內核) 3. firefox(Gecko) 可以 4. 三星可以(多余后綴) 5. 小米自帶的手機瀏覽器可以(但filename亂碼) 6. qq, uc(PC都可以) * */ function downloadFile(content, fileName) { //下載base64圖片 const base64ToBlob = function(code) { let parts = code.split(';base64,'); let contentType = parts[0].split(':')[1]; let raw = window.atob(parts[1]); let rawLength = raw.length; let uInt8Array = new Uint8Array(rawLength); for(let i = 0; i < rawLength; ++i) { uInt8Array[i] = raw.charCodeAt(i); } return new Blob([uInt8Array], { type: contentType }); }; let aLink = document.createElement('a'); let blob = base64ToBlob(content); //new Blob([content]); let evt = document.createEvent("HTMLEvents"); evt.initEvent("click", true, true); //initEvent 不加后兩個參數在FF下會報錯 事件類型,是否冒泡,是否阻止瀏覽器的默認行為 aLink.download = fileName; aLink.href = URL.createObjectURL(blob); // aLink.click(); aLink.dispatchEvent(new MouseEvent("click", {bubbles: true, cancelable: true, view: window})); // }
4. 復制剪貼板
/** * 復制進剪貼板 * @param str */ export function copyText(message) { // copy(str){ // let save = function (e){ // e.clipboardData.setData('text/plain',str);//clipboardData對象 // e.preventDefault();//阻止默認行為 // }; // document.addEventListener('copy',save); // return document.execCommand("copy");//使文檔處於可編輯狀態,否則無效 // } let input = document.createElement("textarea"); input.value = message; document.body.appendChild(input); input.select(); input.setSelectionRange(0, input.value.length); document.execCommand('Copy'); document.body.removeChild(input); console.log("復制成功") //"復制成功" }
5. 生成二維碼的canvas(使用jquery 和 jquery.qrcode.js )
// 生成二維碼canvas - 使用jquery 和 jquery.qrcode.js function() { var imgBuffer = $("<div></div>"); imgBuffer.qrcode({ render: 'canvas', width: 0.24 * deviceWidth * ratio, height: 0.24 * deviceWidth * ratio, text: url, foreground: "#000000", correctLevel: 3, minVersion: 1, //src: require("../image/logo-qrcode.png"), }); // var ctx = imgBuffer.children("canvas")[0].getContext("2d"); // this.qrcodeImageObj = imgBuffer.children("canvas")[0]; // this.qrcodeImageSrc = imgBuffer.children("canvas")[0].toDataURL(); // this.qrCodeData = ctx.getImageData(0,0,imgBuffer.children("canvas")[0].width, imgBuffer.children("canvas")[0].height); } // 123
方法二: 使用 npm i qrcode
// 使用 npm i qrcode 的二維碼生成功能 function getQrcodeCanvas = { const _this = this; await QRCode.toCanvas(url, { width: 0.24 * deviceWidth * ratio, height: 0.24 * deviceWidth * ratio, text: url, foreground: "#000000", correctLevel: 3, minVersion: 1, }, function (err, canvas) { var ctx = canvas.getContext("2d"); _this.qrcodeImageObj = canvas; _this.qrcodeImageSrc = canvas.toDataURL(); _this.qrCodeData = ctx.getImageData(0,0, canvas.width, canvas.height); }); }
最后: 實例

1 /** 2 * 使用 3 */ 4 const data = { 5 width: document.body.clientWidth, 6 height: document.body.clientHeight 7 } 8 new DrawInvitation(data, (src, canvas, imageObj, imageSrc) => { 9 // success callback 10 // 顯示 canvas 11 // 顯示 image 12 // 保存 image 13 }, () => { 14 // fail callback 15 }) 16 17 18 19 20 /** 21 * 畫圖 22 */ 23 class DrawCanvas { 24 constructor(data, successCallback, errorCallback) { 25 this.url = "https://123.com"; 26 27 var deviceWidth = data.width ? data.width : window.screen.width; 28 var deviceHeight = data.height ? data.height : window.screen.width * 16/9; 29 var dpr = window.devicePixelRatio || 1; 30 var canvas = $("<canvas id='qrcode-canvas'></canvas>"); 31 canvas.attr("width",deviceWidth); 32 canvas.attr("height",deviceHeight); 33 canvas.css("position", "absolute"); 34 canvas.css("left", "0"); 35 canvas.css("top", "0"); 36 canvas.css("z-index", "1"); 37 // canvas.css("display", "none"); 38 canvas.css("background-color", "#000000"); 39 var ctx = canvas[0].getContext("2d"); 40 var bspr = ctx.webkitBackingStorePixelRatio || 41 ctx.mozBackingStorePixelRatio || 42 ctx.msBackingStorePixelRatio || 43 ctx.oBackingStorePixelRatio || 44 ctx.BackingStorePixelRatio || 1; 45 var ratio = dpr / bspr; 46 canvas.css("width", canvas.attr("width")); 47 canvas.css("height", canvas.attr("height")); 48 canvas.attr("width", canvas.attr("width") * ratio); 49 canvas.attr("height", canvas.attr("height") * ratio); 50 51 this.qrCodeData = null; 52 this.deviceWidth = deviceWidth; 53 this.deviceHeight = deviceHeight; 54 this.ctx = ctx; 55 this.ratio = ratio; 56 this.canvas = canvas; 57 this.successCallback = successCallback; 58 this.errorCallback = errorCallback; 59 } 60 61 /** 62 * 生成二維碼 63 */ 64 async qrCodeCreater(){ 65 // 二維碼的生成路徑 66 let {deviceWidth, ratio} = this; 67 var imgBuffer = $("<div></div>"); 68 let url = this.url; 69 // imgBuffer.qrcode({ 70 // render: 'canvas', 71 // width: 0.24 * deviceWidth * ratio, 72 // height: 0.24 * deviceWidth * ratio, 73 // text: url, 74 // foreground: "#000000", 75 // correctLevel: 3, 76 // minVersion: 1, 77 // //src: require("../image/logo-qrcode.png"), 78 // }); 79 // var ctx = imgBuffer.children("canvas")[0].getContext("2d"); 80 // this.qrcodeImageObj = imgBuffer.children("canvas")[0]; 81 // this.qrcodeImageSrc = imgBuffer.children("canvas")[0].toDataURL(); 82 // this.qrCodeData = ctx.getImageData(0,0,imgBuffer.children("canvas")[0].width, imgBuffer.children("canvas")[0].height); 83 84 const _this = this; 85 await QRCode.toCanvas(url, { 86 width: 0.24 * deviceWidth * ratio, 87 height: 0.24 * deviceWidth * ratio, 88 text: url, 89 foreground: "#000000", 90 correctLevel: 3, 91 minVersion: 1, 92 }, function (err, canvas) { 93 var ctx = canvas.getContext("2d"); 94 _this.qrcodeImageObj = canvas; 95 _this.qrcodeImageSrc = canvas.toDataURL(); 96 _this.qrCodeData = ctx.getImageData(0,0, canvas.width, canvas.height); 97 }); 98 }; 99 100 /** 101 * 生成圖片 102 */ 103 draw() { 104 // 生成二維碼的圖片 105 this.qrCodeCreater(); 106 const _this = this; 107 // var imgBuffer = $("<img></img>"); 108 // imgBuffer.on("load", function() {}) //jquery的監聽從1.8版本開始,不可使用load直接進行 109 var imgBuffer = new Image(); 110 imgBuffer.crossOrigin = "Anonymous"; 111 imgBuffer.src = "圖片1.png"; 112 imgBuffer.onload = function(){ 113 var imgBuffer_2 = new Image(); 114 imgBuffer_2.crossOrigin = "Anonymous"; 115 imgBuffer_2.src = "圖片2.png"; 116 imgBuffer_2.onload = function(){ 117 var imgBuffer_3 = new Image(); 118 imgBuffer_3.crossOrigin = "Anonymous"; 119 imgBuffer_3.src = "圖片3.png"; 120 imgBuffer_3.onload = function(){ 121 _this.drawCanvas(imgBuffer, imgBuffer_2, imgBuffer_3); 122 }; 123 imgBuffer_3.onerror = function () { 124 showErrorMessage(i18n.home.generate_card_fail, _this.errorCallback); //'生成邀請函失敗!' 125 }; 126 }; 127 imgBuffer_2.onerror = function () { 128 showErrorMessage(i18n.home.generate_card_fail, _this.errorCallback); //'生成邀請函失敗!' 129 } 130 }; 131 imgBuffer.onerror = function () { 132 showErrorMessage(i18n.home.generate_card_fail, _this.errorCallback); //'生成邀請函失敗!' 133 } 134 } 135 136 /** 137 * onload 圖片后合成canvas 138 * @param imgBuffer 139 * @param imgBuffer_2 140 */ 141 drawCanvas(imgBuffer, imgBuffer_2, imgBuffer_3) { 142 let {qrCodeData, ctx, canvas, deviceWidth, deviceHeight, ratio, successCallback} = this; 143 ctx.clearRect(0,0,canvas.attr("width"), canvas.attr("height")); 144 //背景顏色 145 ctx.fillStyle = "#ffffff"; 146 ctx.fillRect(0, 0, canvas.attr("width"), canvas.attr("height")); 147 ctx.textAlign="center"; 148 // ctx.drawImage(imgBuffer, 0, 0, canvas.attr("width"), canvas.attr("height")); 149 150 let canvasWidth= canvas.attr("width"), canvasHeight = canvas.attr("height"); 151 // 頂部橙色圓弧背景 152 ctx.beginPath(); 153 // ctx.arc(300, -540, 750, 0, 2*Math.PI); 154 ctx.arc(canvasWidth/6*5, -canvasWidth/9*13.5, canvasWidth/12*25, 0, 2*Math.PI); 155 ctx.stroke(); 156 ctx.fillStyle="#03bcd5"; 157 ctx.fill(); 158 // logo圖片 159 ctx.drawImage(imgBuffer, canvasWidth * 0.2, canvasWidth * 0.14, canvasWidth*0.6, canvasWidth*0.6*0.31466);//0.31466470154753131908621960206338 160 // 底部圖片 161 ctx.drawImage(imgBuffer_2, canvasWidth * 0.382/2, canvasHeight-canvasWidth * 0.618, canvasWidth * 0.618, canvasWidth * 0.618); 162 // 二維碼背景 163 ctx.beginPath(); 164 ctx.rect(canvasWidth*0.38-canvasWidth*0.01, canvasHeight*0.59-canvasWidth*0.008, qrCodeData.width+canvasWidth*0.02, qrCodeData.height+canvasWidth*0.02); 165 ctx.stroke(); 166 ctx.fillStyle="#ffffff"; 167 ctx.fill(); 168 // 二維碼 169 ctx.putImageData(qrCodeData, canvas.attr("width") * 0.38, canvas.attr("height") * 0.59); 170 171 ctx.drawImage(imgBuffer_3, 172 canvas.attr("width") * 0.38 + this.qrcodeImageObj.width/2 - this.qrcodeImageObj.width/4.7/2, 173 canvas.attr("height") * 0.59 + this.qrcodeImageObj.height/2 - this.qrcodeImageObj.height/4.7/2, 174 this.qrcodeImageObj.width/4.7, 175 this.qrcodeImageObj.height/4.7); 176 177 //文字顏色 178 ctx.fillStyle = "#000000"; 179 var in_text3 = "123456789"; 180 var in_text4 = "123456789"; 181 var in_text5 = "123456789"; 182 var in_text6 = "123456789"; 183 184 // 1 185 ctx.font= "900 " + deviceWidth * ratio / (getCurrentInputLength(in_text3) * 1 > 12 ? getCurrentInputLength(in_text3) * 1 : 12) +"px 微軟雅黑"; 186 ctx.fillText(in_text3, 0.5 * deviceWidth * ratio , 0.42 * deviceHeight * ratio); 187 // 2 188 this.fillTextAndAutoChangeLine(ctx, deviceWidth, ratio, deviceHeight, in_text4); 189 // 3 190 ctx.font= "bold " + deviceWidth * ratio / 22 + "px exo, JiaLiDaYuan, 微軟雅黑"; 191 ctx.fillText(in_text5, 0.5 * deviceWidth * ratio , 0.815 * deviceHeight * ratio); 192 ctx.fillText(in_text6, 0.5 * deviceWidth * ratio, 0.855 * deviceHeight * ratio); 193 194 // $("#imgBox").children("img").attr("src", canvas[0].toDataURL()); 195 successCallback(canvas[0].toDataURL(), canvas, this.qrcodeImageObj, this.qrcodeImageSrc); 196 } 197 198 199 /** 繪制文字時自動換行 */ 200 fillTextAndAutoChangeLine(ctx, deviceWidth, ratio, deviceHeight, text) { 201 ctx.font= deviceWidth * ratio / 22 +"px 微軟雅黑"; 202 // 一個字符的寬度 203 const oneCharWidth = ctx.measureText("M").width; 204 // canvas的寬度, 這里特意少個字符 205 const canvasWidth = deviceWidth * ratio - 3 * oneCharWidth; 206 const len = text.length; 207 // 初始Y的距離 208 let initY = 0.45 * deviceHeight * ratio; 209 const lineHeight = 0.03 * deviceHeight * ratio; 210 // 預存字符串 211 let preWriteText = ""; 212 let preWriteTextWidth = 0; 213 // 整個單詞, 遇到不完整的就換行 214 let totalWord = ""; 215 for (let i = 0; i < len; i ++) { 216 const char = text.charAt(i); 217 // 判斷是否遇到空格 218 if (char === " ") { 219 totalWord = ""; 220 } else { 221 totalWord += char; 222 } 223 // 計算字體的寬度 224 const charWidth = ctx.measureText(char).width; 225 preWriteTextWidth += charWidth; 226 // 如果大於cavas寬度並且不是最后一個字符並且是一個完整的單次, 則將這行寫下來, 並換行 227 if (i != len - 1 && preWriteTextWidth >= canvasWidth) { 228 // 通過下一個是不是空格判斷是不是一個完整的單次 229 if (char != " "&& preWriteText.indexOf(" ") !== -1) { 230 // 不是完整的單次, 則退回到單次開頭 231 const wordFirstCharPos = preWriteText.length - totalWord.length + 1; 232 preWriteText = preWriteText.substring(0, wordFirstCharPos); 233 initY += lineHeight; 234 ctx.fillText(preWriteText, 0.5 * deviceWidth * ratio , initY); 235 i -= totalWord.length; 236 // 單次的第一個字母 237 const wordFirstChar = text.charAt(wordFirstCharPos); 238 preWriteText = ""; 239 preWriteTextWidth = 0; 240 } 241 // 下一個不是空格, 並且這一行中沒有空格, 則把這行寫下來 || 242 else { 243 initY += lineHeight; 244 // 當前單次切掉, 確保不爆框 245 preWriteText = preWriteText.substring(0, preWriteText.length); 246 ctx.fillText(preWriteText, 0.5 * deviceWidth * ratio , initY); 247 // 換行 248 preWriteText = char; 249 preWriteTextWidth = charWidth; 250 } 251 } else { 252 preWriteText += char; 253 } 254 // 直到最后一個字 255 if (i == len - 1) { 256 initY += lineHeight; 257 ctx.fillText(preWriteText, 0.5 * deviceWidth * ratio , initY); 258 } 259 } 260 } 261 }