最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

移動(dòng)端 Vue+Vant 的Uploader 實(shí)現(xiàn)上傳、壓縮、旋轉(zhuǎn)圖片功能

 更新時(shí)間:2019年06月10日 11:48:38   作者:我想當(dāng)個(gè)土老板  
這篇文章主要介紹了移動(dòng)端 Vue+Vant 的Uploader 實(shí)現(xiàn) 上傳、壓縮、旋轉(zhuǎn)圖片功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下

面向百度開(kāi)發(fā)

html

 <van-uploader :after-read="onRead" accept="image/*">
    <img src="./icon_input_add.png" />
 </van-uploader>

js

data() {
    return {
      files: {
        name: "",
        type: ""
      },
      headerImage: null,
      picValue: null,
      upImgUrl,
    }
  },
  // 組件方法 獲取 流
  async onRead(file) {
      // console.log(file);
      // console.log(file.file);
      this.files.name = file.file.name; // 獲取文件名
      this.files.type = file.file.type; // 獲取類型
      this.picValue = file.file; // 文件流
      this.imgPreview(this.picValue);
    },
    // 處理圖片
    imgPreview(file) {
      let self = this;
      let Orientation;
      //去獲取拍照時(shí)的信息,解決拍出來(lái)的照片旋轉(zhuǎn)問(wèn)題
      Exif.getData(file, function () {
        Orientation = Exif.getTag(this, "Orientation");
      });
      // 看支持不支持FileReader
      if (!file || !window.FileReader) return;
      if (/^image/.test(file.type)) {
        // 創(chuàng)建一個(gè)reader
        let reader = new FileReader();
        // 將圖片2將轉(zhuǎn)成 base64 格式
        reader.readAsDataURL(file);
        // 讀取成功后的回調(diào)
        reader.onloadend = function () {
          // console.log(this.result);
          let result = this.result;
          let img = new Image();
          img.src = result;
          //判斷圖片是否大于500K,是就直接上傳,反之壓縮圖片
          if (this.result.length <= 500 * 1024) {
            self.headerImage = this.result;
            self.postImg();
          } else {
            img.onload = function () {
              let data = self.compress(img, Orientation);
              self.headerImage = data;
              self.postImg();
            };
          }
        };
      }
    },
    // 壓縮圖片
    compress(img, Orientation) {
      let canvas = document.createElement("canvas");
      let ctx = canvas.getContext("2d");
      //瓦片canvas
      let tCanvas = document.createElement("canvas");
      let tctx = tCanvas.getContext("2d");
      // let initSize = img.src.length;
      let width = img.width;
      let height = img.height;
      //如果圖片大于四百萬(wàn)像素,計(jì)算壓縮比并將大小壓至400萬(wàn)以下
      let ratio;
      if ((ratio = (width * height) / 4000000) > 1) {
        // console.log("大于400萬(wàn)像素");
        ratio = Math.sqrt(ratio);
        width /= ratio;
        height /= ratio;
      } else {
        ratio = 1;
      }
      canvas.width = width;
      canvas.height = height;
      //    鋪底色
      ctx.fillStyle = "#fff";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      //如果圖片像素大于100萬(wàn)則使用瓦片繪制
      let count;
      if ((count = (width * height) / 1000000) > 1) {
        // console.log("超過(guò)100W像素");
        count = ~~(Math.sqrt(count) + 1); //計(jì)算要分成多少塊瓦片
        //      計(jì)算每塊瓦片的寬和高
        let nw = ~~(width / count);
        let nh = ~~(height / count);
        tCanvas.width = nw;
        tCanvas.height = nh;
        for (let i = 0; i < count; i++) {
          for (let j = 0; j < count; j++) {
            tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
            ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
          }
        }
      } else {
        ctx.drawImage(img, 0, 0, width, height);
      }
      //修復(fù)ios上傳圖片的時(shí)候 被旋轉(zhuǎn)的問(wèn)題
      if (Orientation != "" && Orientation != 1) {
        switch (Orientation) {
          case 6: //需要順時(shí)針(向左)90度旋轉(zhuǎn)
            this.rotateImg(img, "left", canvas);
            break;
          case 8: //需要逆時(shí)針(向右)90度旋轉(zhuǎn)
            this.rotateImg(img, "right", canvas);
            break;
          case 3: //需要180度旋轉(zhuǎn)
            this.rotateImg(img, "right", canvas); //轉(zhuǎn)兩次
            this.rotateImg(img, "right", canvas);
            break;
        }
      }
      //進(jìn)行最小壓縮
      let ndata = canvas.toDataURL("image/jpeg", 0.1);
      tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
      return ndata;
    },
    // 旋轉(zhuǎn)圖片
    rotateImg(img, direction, canvas) {
      //最小與最大旋轉(zhuǎn)方向,圖片旋轉(zhuǎn)4次后回到原方向
      const min_step = 0;
      const max_step = 3;
      if (img == null) return;
      //img的高度和寬度不能在img元素隱藏后獲取,否則會(huì)出錯(cuò)
      let height = img.height;
      let width = img.width;
      let step = 2;
      if (step == null) {
        step = min_step;
      }
      if (direction == "right") {
        step++;
        //旋轉(zhuǎn)到原位置,即超過(guò)最大值
        step > max_step && (step = min_step);
      } else {
        step--;
        step < min_step && (step = max_step);
      }
      //旋轉(zhuǎn)角度以弧度值為參數(shù)
      let degree = (step * 90 * Math.PI) / 180;
      let ctx = canvas.getContext("2d");
      switch (step) {
        case 0:
          canvas.width = width;
          canvas.height = height;
          ctx.drawImage(img, 0, 0);
          break;
        case 1:
          canvas.width = height;
          canvas.height = width;
          ctx.rotate(degree);
          ctx.drawImage(img, 0, -height);
          break;
        case 2:
          canvas.width = width;
          canvas.height = height;
          ctx.rotate(degree);
          ctx.drawImage(img, -width, -height);
          break;
        case 3:
          canvas.width = height;
          canvas.height = width;
          ctx.rotate(degree);
          ctx.drawImage(img, -width, 0);
          break;
      }
    },
    //將base64轉(zhuǎn)換為文件
    dataURLtoFile(dataurl) {
      var arr = dataurl.split(","),
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], this.files.name, {
        type: this.files.type
      });
    },
    //這里寫(xiě)接口 
    async postImg() {
      let file = this.dataURLtoFile(this.headerImage);
      let formData = new window.FormData();
      formData.append("file", file);
      toast_loding(this, "圖片上傳中···");
      try {
        let res = await util.ajax.post(this.upImgUrl, formData, {
          headers: {
            "Content-Type": "multipart/form-data"
          }
        });
      } catch (e) {
        console.log(e);
      }
    }

總結(jié)

以上所述是小編給大家介紹的移動(dòng)端 Vue+Vant 的Uploader 實(shí)現(xiàn)上傳、壓縮、旋轉(zhuǎn)圖片功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝! 

相關(guān)文章

  • vue面試??贾甤omputed是如何實(shí)現(xiàn)的

    vue面試??贾甤omputed是如何實(shí)現(xiàn)的

    對(duì)于每天都在用的計(jì)算屬性(computed),小編猜大家肯定也想窺探其奧妙與原理對(duì)吧,所以這篇文章就來(lái)講講computed是如何實(shí)現(xiàn)的吧,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-08-08
  • 淺談vuex的基本用法和mapaction傳值問(wèn)題

    淺談vuex的基本用法和mapaction傳值問(wèn)題

    今天小編就為大家分享一篇淺談vuex的基本用法和mapaction傳值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-11-11
  • vue項(xiàng)目main.js配置及使用方法

    vue項(xiàng)目main.js配置及使用方法

    main.js是項(xiàng)目的入口文件,項(xiàng)目中所有的頁(yè)面都會(huì)加載main.js,本文主要介紹了vue項(xiàng)目main.js配置及使用方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2023-05-05
  • VUE +Element 實(shí)現(xiàn)多個(gè)字段值拼接功能

    VUE +Element 實(shí)現(xiàn)多個(gè)字段值拼接功能

    這篇文章主要介紹了VUE +Element 實(shí)現(xiàn)多個(gè)字段值拼接,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • vue使用keep-alive后清除緩存的方法

    vue使用keep-alive后清除緩存的方法

    這篇文章主要給大家介紹了關(guān)于vue使用keep-alive后清除緩存的相關(guān)資料,這個(gè)問(wèn)題在我們?nèi)粘9ぷ髦薪?jīng)常會(huì)用到,本文通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-08-08
  • Vue?cli3.0創(chuàng)建Vue項(xiàng)目的簡(jiǎn)單過(guò)程記錄

    Vue?cli3.0創(chuàng)建Vue項(xiàng)目的簡(jiǎn)單過(guò)程記錄

    Vue CLI是一個(gè)基于Vue.js進(jìn)行快速開(kāi)發(fā)的完整系統(tǒng),下面這篇文章主要給大家介紹了關(guān)于Vue?cli3.0創(chuàng)建Vue項(xiàng)目的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • vue2項(xiàng)目中如何使用clipboard復(fù)制插件

    vue2項(xiàng)目中如何使用clipboard復(fù)制插件

    這篇文章主要介紹了vue2項(xiàng)目中如何使用clipboard復(fù)制插件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • vue版日歷組件的實(shí)現(xiàn)方法

    vue版日歷組件的實(shí)現(xiàn)方法

    這篇文章主要為大家詳細(xì)介紹了vue版日歷組件的實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 登錄頁(yè)面的實(shí)現(xiàn)及跳轉(zhuǎn)代碼實(shí)例(vue-router)

    登錄頁(yè)面的實(shí)現(xiàn)及跳轉(zhuǎn)代碼實(shí)例(vue-router)

    在Vue.js中可以使用vue-router來(lái)實(shí)現(xiàn)前端路由,通過(guò)路由來(lái)跳轉(zhuǎn)頁(yè)面,這篇文章主要給大家介紹了關(guān)于登錄頁(yè)面的實(shí)現(xiàn)及跳轉(zhuǎn)(vue-router)的相關(guān)資料,需要的朋友可以參考下
    2023-12-12
  • vue自定義組件@click點(diǎn)擊失效問(wèn)題及解決

    vue自定義組件@click點(diǎn)擊失效問(wèn)題及解決

    這篇文章主要介紹了vue自定義組件@click點(diǎn)擊失效問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04

最新評(píng)論

墨竹工卡县| 叙永县| 延川县| 长春市| 来凤县| 台山市| 庆云县| 东兰县| 密云县| 久治县| 通江县| 平远县| 曲水县| 专栏| 宜阳县| 扎囊县| 乐至县| 永城市| 九龙县| 赣榆县| 鲁山县| 大化| 延安市| 新蔡县| 鄯善县| 广水市| 嘉峪关市| 广西| 清丰县| 宝清县| 民权县| 小金县| 平遥县| 苏州市| 华容县| 舟曲县| 来宾市| 沙湾县| 宜兰市| 台前县| 新野县|