vue头像上传压缩
Posted 妞妞不安
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue头像上传压缩相关的知识,希望对你有一定的参考价值。
安装插件
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>
以上是关于vue头像上传压缩的主要内容,如果未能解决你的问题,请参考以下文章
vue中使用axios post上传头像/图片并实时显示到页面