vue 移動端拍照壓縮base64格式上傳


啰嗦兩句,因最近有個小項目要做一個拍照上傳頭像的功能,做的過程中出現了一些問題,針對這些問題做一下總結分享

問題:

  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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM