功能需求:javascript
實現本地圖片裁剪功能,要求裁剪獲得的圖片像素在420-1500px之間,不大於2M,並將裁剪後圖片傳給後臺css
使用插件:前端
Cropper(項目地址:https://github.com/fengyuanchen/cropper)實現裁剪java
Web Uploader(項目地址:https://github.com/fex-team/webuploader)實現圖片上傳git
功能實現:github
1.HTMLweb
1 <div> 2 <div class="up-pick"> 3 <a href="javascript:void(0)" id="picker">上傳圖片</a> 4 </div> 5 <input type="file" class="fileInput" hidden /> 6 </div>
2.CSScanvas
引入cropper.css文件app
3.JS函數
因爲cropper依賴於jQuery,這裏引入jQuery,cropper.js和webuploader.js
1 // 觸發input file 2 $("#picker").on('click', function () { 3 $(this).parents(".up-pick").siblings(".fileInput").trigger("click"); 4 });
編寫input file change事件
1 $(".fileInput").on('change', function() { 2 var file = this.files[0]; //獲取上傳圖片,IE有兼容性問題 3 4 //檢測圖片格式和大小的合理性,在這裏爲了簡便,用console.log。實際項目中可用Dialog組件作彈窗提示 5 if(!(file.type == 'image/jpeg' || file.type == 'image/jpg' || file.type == 'image/gif' || file.type == 'image/png')) { 6 console.log('支持圖片格式:GIF、JPG、JPEG、PNG'); 7 $(".fileInput").val(''); 8 return; 9 }else if(file.size > 2097152) { 10 console.log('圖片大小不超過2M'), 11 $(".fileInput").val('');//這裏若不清空,再次傳入同一張圖片,input file的change事件不會觸發 12 return; 13 } 14 15 // 初始化WebUploader 16 var uploader = WebUploader.create({ 17 auto: true,// 選完文件後,是否自動上傳。 18 server: '/Image/productImageUploader',// 文件接收服務端。 19 fileSingleSizeLimit: 2 * 1024 * 1024, 20 duplicate: true, 21 accept: {// 只容許選擇圖片文件。 22 title: 'Images', 23 extensions: 'jpg,jpeg,png', 24 mimeTypes: 'image/jpg,image/jpeg,image/png' 25 } 26 }); 27 28 var image; //上傳的圖片 29 var cropper; //cropper對象 30 var reader = new FileReader(); 31 32 reader.onload = function() { 33 var url = reader.result; 34 var cropperImg = new Image(); //這步操做是爲了拿到圖片的尺寸 35 cropperImg.src = url; 36 37 cropperImg.onload = function() { 38 if(this.width < 420 || this.height < 420){ 39 console.log('圖片尺寸應大於420*420像素'); 40 $(".fileInput").val('') 41 return; 42 } 43 44 //全部檢測經過,彈出彈窗,在彈窗中進行圖片裁剪操做 45 new Dialog({ 46 title: "裁剪圖片", 47 content: '<div class="modifyBg"><div class="imgWrapper"><img id="image" src="' + url + '"></div></div>', 48 button: [{ 49 value: '肯定', 50 callback: function () { 51 var type = $(image).attr('src').split(';')[0].split(':')[1];//得出圖片格式:相似image/jpeg 52 var canVas = cropper.getCroppedCanvas();//獲取裁剪後獲得的canvas數據 53 var file = convertBase64UrlToBlob(canVas.toDataURL('image/jpeg','0.0'));//將canvas轉換爲Blob格式 54 uploader.addFiles(file);//將裁剪後的圖片添加進webuploader上傳到後臺 55 this.close(); 56 } 57 }, { 58 value: '取消', 59 callback: function () { 60 $(".fileInput").val('') 61 this.close(); 62 } 63 }] 64 }).show(); 65 66 // 圖片上傳 67 image = document.querySelector('#image'); 68 cropper = new Cropper(image, { 69 viewMode: 1, //裁剪框只能在圖片範圍內移動 70 dragMode: 'move', //圖片能夠拖動 71 aspectRatio: 1, //裁剪比例,NaN-自由選擇區域 72 zoomable: false, //禁止縮放,在控制裁剪像素,容許縮放會有問題 73 ready: function() { 74 cropper.setData({//初始裁剪區域佔圖片比例 75 width: 420, 76 height: 420 77 }) 78 }, 79 cropmove: function() { 80 var data = cropper.getData() 81 if(data.width > 1500 || data.height > 1500) { 82 cropper.setData({ 83 width: 1500, 84 height: 1500 85 }) 86 } 87 if(data.width < 420 || data.height < 420) { 88 cropper.setData({ 89 width: 420, 90 height: 420 91 }) 92 } 93 } 94 }); 95 }; 96 } 97 reader.readAsDataURL(file);//File對象轉換爲dataURL 98 99 uploader.on('uploadSuccess', function(file, rs) { 100 // 圖片上傳回調函數 101 }); 102 103 uploader.on('startUpload', function(file, rs) { 104 console.log("文件正在上傳中,請稍候"); 105 }); 106 }
1 function convertBase64UrlToBlob(urlData){ 2 var bytes=window.atob(urlData.split(',')[1]);//去掉url的頭,並轉換爲byte 3 4 //處理異常,將ascii碼小於0的轉換爲大於0 5 var ab = new ArrayBuffer(bytes.length); 6 var ia = new Uint8Array(ab); 7 for (var i = 0; i < bytes.length; i++) { 8 ia[i] = bytes.charCodeAt(i); 9 } 10 11 return new Blob( [ab] , {type : 'image/jpeg'}); 12 }
列幾個這裏踩到的坑:
①圖片裁剪前限制2M,但出現裁剪後圖片大於2M的狀況:
發現canVas.toDataURL方法接收兩個參數,不傳的話默認轉爲image/png格式,圖片質量爲1.0。這樣就致使了裁剪後獲得的圖片大大大於原始圖片。
查文檔看到
若是type
參數的值爲image/jpeg或
image/webp
,則第二個參數的值若是在0.0和1.0之間的話,會被看做是圖片質量參數,若是第二個參數的值不在0.0和1.0之間,則會使用默認的圖片質量.
因而我這裏修改成 canVas.toDataURL('image/jpeg','0.0')
②因爲技術棧使用webuploader結合cropper實現裁剪上傳,這裏我用了input file,整個的邏輯就是
經過change事件對圖片格式和大小作合理性檢驗 → 經過H5中FileReader獲取圖片base64格式url → 再結合new Image()拿到圖片尺寸,對圖片尺寸作檢驗 → 進入裁剪階段經過cropper.ready方法初始化裁剪框爲圖片像素420的大小,裁剪過程cropmove方法實時控制裁剪框的最大最小尺寸 → cropper.getCroppedCanvas獲取裁剪後獲得的canvas數據 → canVas.toDataURL轉爲base64格式 → 自定義convertBase64UrlToBlob方法將base64轉爲blob圖片格式 → webuploader.addFiles方法上傳最終的圖片
③其實整個圖片裁剪上傳的過程並不難,主要是兩個插件以及H5的API的運用,再結合實際的項目需求理清邏輯,按照需求實現功能。
最後:
從實習到正式,進入前端開發工做將近兩年了,最近在項目開發中遇到一些問題,實際上是之前曾經遇到過的,可是卻不能很清晰記起之前是如何解決的,致使還要再去從新搜索回顧,解決問題的效率大大變慢。
因而以爲總結和思考,這項區別人與人之間能力差距的一個重要因素,更應該去重視和鍛鍊。
但願本身不要懶惰。