1. 程式人生 > >vue-cli 關於圖片頭像上傳壓縮的插件

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

ade -c init 問題 scrip file image() idt 判斷圖片

安裝插件

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-cli 關於圖片頭像上傳壓縮的插件