純前端實現本地圖片裁剪上傳功能(Cropper & Web Uploader結合使用)

功能需求: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 }                                                        
將以base64的圖片url數據轉換爲Blob用webuploader上傳給後臺
 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的運用,再結合實際的項目需求理清邏輯,按照需求實現功能。

 

最後:

從實習到正式,進入前端開發工做將近兩年了,最近在項目開發中遇到一些問題,實際上是之前曾經遇到過的,可是卻不能很清晰記起之前是如何解決的,致使還要再去從新搜索回顧,解決問題的效率大大變慢。

因而以爲總結和思考,這項區別人與人之間能力差距的一個重要因素,更應該去重視和鍛鍊。

但願本身不要懶惰。

相關文章
相關標籤/搜索