啰嗦兩句,因最近有個小項目要做一個拍照上傳頭像的功能,做的過程中出現了一些問題,針對這些問題做一下總結分享
問題:
1.圖片轉base64
2.手機拍照在ios和小米等手機下會旋轉
3.圖片的壓縮
4.手機像素太大,進行一個等比縮放上傳
啰嗦完了,上代碼
<template> <div id="face"> <div class="faceBox"> <img src="" alt="" id="faceImg" ref="faceImg"> </div> <p>請拍攝清晰的全部人臉信息以方便您的進場</p> <img src="../../static/images/example.png" alt="" class="example"> <div class="startFaceBtn" v-show="!openVideo"> <button class="startFace">開始拍攝</button> <input type="file" id="upimg" accept="image/*" @change="upLoad"> </div> <button class="startFace" v-show="openVideo" @click="submit">開始上傳</button> </div> </template>
上面是頁面的布局
關於處理圖片旋轉的問題需要使用 Exif
npm install exif-js
然后在main.js中引入
import EXIF from 'exif-js'
Vue.prototype.Exif = EXIF
<script> import { Indicator } from 'mint-ui'; export default { name: 'face', data() { return { openVideo: false, imgUrl: null, } }, mounted() { }, methods: { upLoad(e) { let files = e.target.files || e.dataTransfer.files; if (!files.length) return; this.picavalue = files[0]; console.log(this.picavalue.size / 1024); if (this.picavalue.size / 1024 > 10000) { this.$message({ message: "圖片過大不支持上傳", type: "warning" }); } else { this.imgPreview(this.picavalue); } }, imgPreview(file, callback) { let that= this; let Orientation //這里的Exif是判斷圖片旋轉的 that.Exif.getData(file, function () { Orientation = that.Exif.getTag(file, 'Orientation'); }); if (!file || !window.FileReader) return; if (/^image/.test(file.type)) { let reader = new FileReader(); reader.readAsDataURL(file) reader.onloadend = function() { let result = this.result; let img = new Image(); img.src = result; img.onload = () => { let data = that.compress(img, Orientation); that.imgUrl = result; that.imgUrl = data console.log(data) that.$refs.faceImg.src = data that.openVideo = true }; }; } }, compress(img, Orientation) { let canvas = document.createElement("canvas"); let ctx = canvas.getContext("2d"); let initSize = img.src.length; let width = img.width/3.5; let height = img.height/3.5; canvas.width = width; canvas.height = height; ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0, width, height); console.log(Orientation) //處理ios手機旋轉角度問題 if (navigator.userAgent.match(/iphone/i)) { if(Orientation != "" && Orientation != 1){ switch(Orientation){ case 6: this.rotateImg(img,'left',canvas); break; case 8: this.rotateImg(img,'right',canvas); break; case 3: this.rotateImg(img,'right',canvas);//轉兩次 this.rotateImg(img,'right',canvas); break; } } }else{ //處理其安卓類手機圖片旋轉的問題 if(Orientation != "" && Orientation != 1){ switch(Orientation){ case 6: this.rotateImg(img,'left',canvas); break; case 8: this.rotateImg(img,'right',canvas); break; case 3: this.rotateImg(img,'right',canvas); this.rotateImg(img,'right',canvas); break; } } } // ndata 為base64格式的圖片上傳時可直接使用,根據清晰度的要求進行調整,這里我用的是0.4 var ndata = canvas.toDataURL("image/jpeg", 0.4); return ndata; }, rotateImg (img, direction,canvas) { //最小與最大旋轉方向,圖片旋轉4次后回到原方向 const min_step = 0; const max_step = 3; if (img == null)return; //img的高度和寬度不能在img元素隱藏后獲取,否則會出錯 //這里因為圖片像素太大進行了一個3.5倍的縮放 let height = img.height/3.5; let width = img.width/3.5; let step = 2; if (step == null) { step = min_step; } if (direction == 'right') { step++; //旋轉到原位置,即超過最大值 step > max_step && (step = min_step); } else { step--; step < min_step && (step = max_step); } //旋轉角度以弧度值為參數 let degree = step * 90 * Math.PI / 180; let ctx = canvas.getContext('2d'); console.log(step) switch (step) { case 0: canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0, width, height); break; case 1: canvas.width = height; canvas.height = width; ctx.rotate(degree); ctx.drawImage(img, 0, -height, width, height); break; case 2: canvas.width = width; canvas.height = height; ctx.rotate(degree); ctx.drawImage(img, -width, -height, width, height); break; case 3: canvas.width = height; canvas.height = width; ctx.rotate(degree); ctx.drawImage(img, -width, 0, width, height); break; } }, submit() { //點擊按鈕處理上傳圖片的邏輯就行了,這里就不做介紹了
} } } </script>
文章參照:https://blog.csdn.net/xiaogezl/article/details/70156500