js 的canvas使用 -- canvas轉圖片、圖片轉canvas、base64圖片下載到本地、復制剪貼板、生成二維碼的canvas


 

將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 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM