vue-cli 关于图片头像上传压缩的插件

安装插件

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>  

猜你喜欢

转载自www.cnblogs.com/nanjie/p/9008376.html