vue-cli 關於圖片頭像上傳壓縮的插件

安裝插件ios

exif-js

 

  1 <template>  
  2   <div>  
  3     <div style="padding:20px;">  
  4       <div class="show">  
  5         <div class="picture" :style="'backgroundImage:url('+headerImage+')'"></div>  
  6       </div>  
  7       <div style="margin-top:20px;">  
  8         <input type="file" id="upload" accept="image" @change="upload">  
  9         <label for="upload"></label>  
 10       </div>  
 11     </div>  
 12   </div>  
 13 </template>  
 14   
 15 <script>  
 16 import Exif from 'exif-js'  
 17   
 18 export default {  
 19   data () {  
 20     return {  
 21       headerImage:'',picValue:''  
 22     }  
 23   },  
 24   mounted () {  
 25   },  
 26   methods: {  
 27     upload (e) {  
 28       let files = e.target.files || e.dataTransfer.files;  
 29       if (!files.length) return;  
 30       this.picValue = files[0];  
 31       this.imgPreview(this.picValue);  
 32     },  
 33     imgPreview (file) {  
 34       let self = this;  
 35       let Orientation;  
 36       //去獲取拍照時的信息,解決拍出來的照片旋轉問題  
 37       Exif.getData(file, function(){  
 38           Orientation = Exif.getTag(this, 'Orientation');  
 39       });  
 40       // 看支持不支持FileReader  
 41       if (!file || !window.FileReader) return;  
 42   
 43       if (/^image/.test(file.type)) {  
 44           // 建立一個reader  
 45           let reader = new FileReader();  
 46           // 將圖片2將轉成 base64 格式  
 47           reader.readAsDataURL(file);  
 48           // 讀取成功後的回調  
 49           reader.onloadend = function () {  
 50             let result = this.result;  
 51             let img = new Image();  
 52             img.src = result;  
 53             //判斷圖片是否大於100K,是就直接上傳,反之壓縮圖片  
 54             if (this.result.length <= (100 * 1024)) {  
 55               self.headerImage = this.result;  
 56               self.postImg();  
 57             }else {  
 58               img.onload = function () {  
 59                 let data = self.compress(img,Orientation);  
 60                 self.headerImage = data;  
 61                 self.postImg();  
 62               }  
 63             }  
 64           }   
 65         }  
 66       },  
 67       postImg () {  
 68         //這裏寫接口  
 69       },  
 70       rotateImg (img, direction,canvas) {  
 71         //最小與最大旋轉方向,圖片旋轉4次後回到原方向      
 72         const min_step = 0;      
 73         const max_step = 3;        
 74         if (img == null)return;      
 75         //img的高度和寬度不能在img元素隱藏後獲取,不然會出錯      
 76         let height = img.height;      
 77         let width = img.width;        
 78         let step = 2;      
 79         if (step == null) {      
 80             step = min_step;      
 81         }      
 82         if (direction == 'right') {      
 83             step++;      
 84             //旋轉到原位置,即超過最大值      
 85             step > max_step && (step = min_step);      
 86         } else {      
 87             step--;      
 88             step < min_step && (step = max_step);      
 89         }       
 90         //旋轉角度以弧度值爲參數      
 91         let degree = step * 90 * Math.PI / 180;      
 92         let ctx = canvas.getContext('2d');      
 93         switch (step) {      
 94           case 0:      
 95               canvas.width = width;      
 96               canvas.height = height;      
 97               ctx.drawImage(img, 0, 0);      
 98               break;      
 99           case 1:      
100               canvas.width = height;      
101               canvas.height = width;      
102               ctx.rotate(degree);      
103               ctx.drawImage(img, 0, -height);      
104               break;      
105           case 2:      
106               canvas.width = width;      
107               canvas.height = height;      
108               ctx.rotate(degree);      
109               ctx.drawImage(img, -width, -height);      
110               break;      
111           case 3:      
112               canvas.width = height;      
113               canvas.height = width;      
114               ctx.rotate(degree);      
115               ctx.drawImage(img, -width, 0);      
116               break;  
117         }      
118     },  
119     compress(img,Orientation) {  
120       let canvas = document.createElement("canvas");  
121       let ctx = canvas.getContext('2d');  
122         //瓦片canvas  
123       let tCanvas = document.createElement("canvas");  
124       let tctx = tCanvas.getContext("2d");  
125       let initSize = img.src.length;  
126       let width = img.width;  
127       let height = img.height;  
128       //若是圖片大於四百萬像素,計算壓縮比並將大小壓至400萬如下  
129       let ratio;  
130       if ((ratio = width * height / 4000000) > 1) {  
131         console.log("大於400萬像素")  
132         ratio = Math.sqrt(ratio);  
133         width /= ratio;  
134         height /= ratio;  
135       } else {  
136         ratio = 1;  
137       }  
138       canvas.width = width;  
139       canvas.height = height;  
140   //        鋪底色  
141       ctx.fillStyle = "#fff";  
142       ctx.fillRect(0, 0, canvas.width, canvas.height);  
143       //若是圖片像素大於100萬則使用瓦片繪製  
144       let count;  
145       if ((count = width * height / 1000000) > 1) {  
146         console.log("超過100W像素");  
147         count = ~~(Math.sqrt(count) + 1); //計算要分紅多少塊瓦片  
148   //            計算每塊瓦片的寬和高  
149         let nw = ~~(width / count);  
150         let nh = ~~(height / count);  
151         tCanvas.width = nw;  
152         tCanvas.height = nh;  
153         for (let i = 0; i < count; i++) {  
154           for (let j = 0; j < count; j++) {  
155             tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);  
156             ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);  
157           }  
158         }  
159       } else {  
160         ctx.drawImage(img, 0, 0, width, height);  
161       }  
162       //修復ios上傳圖片的時候 被旋轉的問題  
163       if(Orientation != "" && Orientation != 1){  
164         switch(Orientation){  
165           case 6://須要順時針(向左)90度旋轉  
166               this.rotateImg(img,'left',canvas);  
167               break;  
168           case 8://須要逆時針(向右)90度旋轉  
169               this.rotateImg(img,'right',canvas);  
170               break;  
171           case 3://須要180度旋轉  
172               this.rotateImg(img,'right',canvas);//轉兩次  
173               this.rotateImg(img,'right',canvas);  
174               break;  
175         }  
176       }  
177       //進行最小壓縮  
178       let ndata = canvas.toDataURL('image/jpeg', 0.1);  
179       console.log('壓縮前:' + initSize);  
180       console.log('壓縮後:' + ndata.length);  
181       console.log('壓縮率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");  
182       tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;  
183       return ndata;  
184     },  
185   }  
186 }  
187 </script>  
188   
189 <style>  
190 *{  
191   margin: 0;  
192   padding: 0;  
193 }  
194 .show {  
195   width: 100px;  
196   height: 100px;  
197   overflow: hidden;  
198   position: relative;  
199   border-radius: 50%;  
200   border: 1px solid #d5d5d5;  
201 }  
202 .picture {  
203   width: 100%;  
204   height: 100%;  
205   overflow: hidden;  
206   background-position: center center;  
207   background-repeat: no-repeat;  
208   background-size: cover;   
209 }  
210 </style>  
相關文章
相關標籤/搜索