移动端头像裁剪上传

作移动端的时候,各位可能会遇到用户上传头像,而前端的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 });
   },
相关文章
相关标签/搜索