最近要寫一個時序圖:當前圖片的前一張和后兩張拼成一張圖。
需求會議上就想到canvas,應該沒問題。看了一早上文檔。查了一些資料。午休起來一小時寫了出來。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>拼長圖</title> </head> <body> <div align="center" class="img_photo"> <img src="http://pre-bj-trace-image.oss-cn-beijing.aliyuncs.com/full/20180919/de963ab401235d894aaf100eb8f12bbd.jpg" width="250px" height="562px"> <img src="http://pre-bj-trace-image.oss-cn-beijing.aliyuncs.com/full/20180919/87ee27637fc789008ea782ce964be44e.jpg" width="250px" height="562px"> <img src="http://pre-bj-trace-image.oss-cn-beijing.aliyuncs.com/full/20180919/f0d50c02c0f2b3f55846aa0183ce675e.jpg" width="250px" height="562px"> <img src="http://pre-bj-trace-image.oss-cn-beijing.aliyuncs.com/full/20180919/ad81e8d020345e7b0a1715e7a680fddb.jpg" width="250px" height="562px"> </div> <button align="center" id='save-img'>合成</button> <div id="image-container"></div> <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script> <script> // 拼出來的圖片的寬度 const height = 300 // 拼出來的圖片的質量,0-1之間,越大質量越好 const encoderOptions = 1 const uploadInput = document.getElementById('save-img'); const imageDiv = document.getElementById('image-container'); uploadInput.addEventListener('click', event => { const data1= new Array(); for(let i=0;i<$('.img_photo img').length;i++){ data1[i]=$('.img_photo img').eq(i).attr('src'); } filesToInstances(data1, instances => { console.log(instances) drawImages(instances, finalImageUrl => { console.log(instances) imageDiv.innerHTML = `<div><a download href=${finalImageUrl}>點擊下載</a><br><img src=${finalImageUrl}></div>` }) }) }) // 根據圖片文件拿到圖片實例 const filesToInstances = (files, callback) => { const length = files.length console.log(files) let instances = [] let finished = 0 files.forEach((file, index) => { console.log(file) getBase64(file).then(function(base64){ let img = base64 const image = new Image() image.src = img image.onload = () => { // 圖片實例化成功后存起來 instances[index] = image finished ++ if (finished === length) { callback(instances) } } },function(err){}); // } }) } // 拼圖 const drawImages = (images, callback) => { console.log(images) const canvas = document.createElement('canvas') canvas.height = height; const widths = images.map(item => {console.log(item); return 250; }); console.log(widths) canvas.width = 1000; console.log(canvas.width) const context = canvas.getContext('2d') let x = 0 images.forEach((item, index) => { const width = widths[index] context.drawImage(item, x, 0, width, height) x += width }) callback(canvas.toDataURL('image/jpeg', encoderOptions)) } // 圖片轉base64 const getBase64 = (img) =>{ const getBase64Image = (img,width,height) => {//width、height調用時傳入具體像素值,控制大小 ,不傳則默認圖像大小 let canvas = document.createElement("canvas"); canvas.width = width ? width : img.width; canvas.height = height ? height : img.height; let ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); let dataURL = canvas.toDataURL(); return dataURL; } let image = new Image(); image.crossOrigin = ''; image.src = img; let deferred=$.Deferred(); if(img){ image.onload = () => { deferred.resolve(getBase64Image(image));//將base64傳給done上傳處理 } return deferred.promise();//問題要讓onload完成后再return sessionStorage['imgTest'] } } </script> </body> </html>
這個有一個對圖片處理成base64的操作方法,很不錯。promise異步執行的!
參考的網站:https://segmentfault.com/a/1190000011684333