移動端頭像裁剪上傳

作移動端的時候,各位可能會遇到用戶上傳頭像,而前端的input:file,若是上傳正方形圖片還好,可是若是是矩形的話,在頭像的顯示這塊,就會顯的很不和諧。前端

前端跟進矩形的圖片,實現裁剪成正方形,並把裁剪後的文件上傳給後臺。canvas

1.初始頁面以下,點擊中間默認頭像觸發input:file點擊,彈出選擇文件框.this

2.開始選擇照片,以下,爲選擇的照片,和選擇照片後的效果圖:3d


3.此時圖片的高度大於寬度,所以能夠上下滾動,選擇想要裁剪的範圍,而後點擊選取(下圖從地鐵導航處開始裁剪)。
code


此時,已經裁剪到正方形圖片,能夠從新拍攝或者上傳給後臺。component



下面是代碼cdn

    setPhoto(e) {//對圖片尺寸作出限制並設置壓縮尺寸
        let _this = this;
        let file = e.target.files[0];
        if (!file) return ''
         //大於6兆,不容許上傳
         if (file.size > this.maxSize * 6) {
                 return; this.$toast('圖片過大,不能大於6M')
           }
         if (file.size > this.maxSize * 3) {//this.maxSize 爲1024 * 1024,設置的一張照片最後
             this.ratio = 0.5;
          } else if (file.size > this.maxSize * 4) {
             this.ratio = 0.4;
           }
           Lrz(file, { width: 1024, quality: this.ratio }) 
           .then((rst) => { //這裏使用Lrz,防止圖片選中後旋轉,若是沒有這個問題,也能夠不使用Lrz,直接把this.file轉換爲bolb對象的圖片顯示出來
            // 把處理的好的圖片給用戶看看唄
           // _this.$refs['avatar_img'].src = rst.base64;
      _this.$refs['clip_avatar'].src = rst.base64;
          _this.$nextTick(() => {
                _this.avater_width_larger_height = _this.$refs['clip_avatar'].height <                    _this.$refs['clip_avatar'].width
           })
          _this.show_clip_img = true;
          return rst;
          }).then((rst) => {
            this.file= rst.file;
          })
    },



    checkClip(e) {//滑動後點擊選取觸發該方法,獲取滾動的x和Y的距離傳給               setPhotoCanvas,以便canvas裁剪。
           let sTop = this.$refs['clip_img'].scrollTop;
           let sLeft = this.$refs['clip_img'].scrollLeft;
           this.setPhotoCanvas(sTop, sLeft);
   },




    setPhotoCanvas(sTop, sLeft) {
             let reader = new FileReader();
             reader.onloadend = (e) => {
             let img = new Image();
             img.onload = () => {
             let w = Math.min(this.maxWidth, img.width);
             let h = img.height * (w / img.width);
             let [sw, sh, short, sx, sy] = [img.width, img.height, 0, 0, 0, 0]
             if (w < h) {
                  short = w;
                  sy = (sTop / document.body.clientWidth) * img.width//這裏頭像裁剪的時候,寬度爲屏幕的寬度,所以document.body.clientWidth。若是正方形的寬度不是屏幕寬度,這裏和sx的獲取都須要替換。
                 sh = sw;
             } else { //w>h
                   short = h;
                   sx = (sLeft / document.body.clientWidth) * img.height
                   sw = sh;
              }
             let canvas = document.createElement('canvas');
             let ctx = canvas.getContext('2d');
              // 設置 canvas 的寬度和高度
             canvas.width = short;
             canvas.height = short;
             ctx.drawImage(img, sx, sy, sw, sh, 0, 0, short, short);
              let base64 = canvas.toDataURL('image/png', this.ratio);
              // 插入到預覽區
             this.$refs[ 'avatar_img'].src = base64;
             this.show_clip_img = false;
             this.file = this.dataURItoBlob(base64);
             console.log('size-------------------' + this.file.size)
         };
         img.src = e.target.result;
       }
     reader.readAsDataURL(this.file);
  },



     dataURItoBlob: function(dataURI) {//把用canvas獲得的base64圖片轉換爲二進制大對象以便傳給後臺
       // convert base64/URLEncoded data component to raw binary data held in a string
let byteString;
       if (dataURI.split(',')[0].indexOf('base64') >= 0) {
           byteString = atob(dataURI.split(',')[1]);
        } else {
            byteString = unescape(dataURI.split(',')[1]);
        }

         // separate out the mime component
         let mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

         // write the bytes of the string to a typed array
         let ia = new Uint8Array(byteString.length);
         for (let i = 0; i < byteString.length; i++) {
             ia[i] = byteString.charCodeAt(i);
          }
          return new Blob([ia], { type: mimeString });
   },
相關文章
相關標籤/搜索