将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', 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, { 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 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 // 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 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 }