美文网首页
原生JS上传并压缩图片-实例

原生JS上传并压缩图片-实例

作者: 你这个锤子 | 来源:发表于2020-06-02 19:00 被阅读0次

    微信小程序和H5页面的实例

    小程序

    wxml

    <view class="identityCard_front" bindtap="reciteimage">
        <view class="img_conver" wx:if="{{!back}}">
            <i-icon type="camera_fill" size="78" class="camera" wx:if="{{!back}}" />
            <view class="imgs" wx:if="{{!back}}">点击上传身份证国徽面</view>
        </view>
        <image src="{{url+back}}" wx:if="{{back}}" class="images" mode="scaleToFill"></image>
    </view>
    <canvas class="canvas" canvas-id="canvas" style="width:{{cWidth}}px;height:{{cHeight}}px; visibility: hidden; position:absolute; z-index: -1;left: -10000rpx;top:-10000rpx"></canvas>
    

    js

    var util = require('../../utils/util.js')
    
    reciteimage: function () {
      this.data.isfront = false;
      var that = this;
      wx.showActionSheet({
        itemList: ['从相册选择', '拍照'],
        success(res) {
          if (res.tapIndex == 0) {
            that.chooseFromPortrait();  // 从相册选择的
          } else if (res.tapIndex == 1) {
            that.takephoto()   // 拍照
          }
        },
        fail(res) {
          console.log(res.errMsg)
        }
      })
    },
    chooseFromPortrait: function () {
      this.setData({
        isHandling: true
      })
      var that = this;
      let maxSize = 500;
      let dWidth = wx.getSystemInfoSync().windowWidth * 2;
      wx.chooseImage({
        count: 1, // 默认9 
        sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
        sourceType: ['album'], // 可以指定来源是相册还是相机,默认二者都有 
        success: function (res) {
          // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片 
          let size = res.tempFiles[0].size;
          if (size > 7168 * 1024) {   // 7MB
            wx.showModal({
              title: '上传失败',
              content: '图片大小不能超过7MB',
              showCancel: false
            })
            that.setData({
              isHandling: false
            })
            return;
          } else if (size > 500 * 1024) {
            // 大于 500kb 小于 7MB 的图片把它压缩到 500kb 再上传
            util.getLessLimitSizeImage('canvas', res.tempFiles[0].path, maxSize, dWidth, function (img) {
              wx.getFileInfo({
                filePath: img,
                success: function (res) {
                  console.log('压缩后:' + res.size / 1024 + 'kb')
                }
              })
              that.setData({
                FilePaths: [img]
              })
              that.transferpic();
            })
          } else {
            that.setData({
              FilePaths: res.tempFilePaths
            })
            that.transferpic();
          }
        },
        complete: function (res) {
          that.setData({
            isHandling: false
          })
        }
      })
    },
    takephoto: function () {
      if (this.data.isHandling) { return; }
      this.setData({
        isHandling: true
      })
      var that = this;
      let maxSize = 500;
      let dWidth = wx.getSystemInfoSync().windowWidth * 2;
      wx.chooseImage({
        count: 1, // 默认9 
        sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
        sourceType: ['camera'], // 可以指定来源是相册还是相机,默认二者都有 
        success: function (res) {
          // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片  
          let size = res.tempFiles[0].size;
          if (size > 7168 * 1024) {   // 7MB
            wx.showModal({
              title: '上传失败',
              content: '图片大小不能超过7MB',
              showCancel: false
            })
            that.setData({
              isHandling: false
            })
            return;
          } else if (size > 500 * 1024) {
            // 大于 500kb 小于 2M 的图片把它压缩到 500kb 再上传
            util.getLessLimitSizeImage('canvas', res.tempFiles[0].path, maxSize, dWidth, function (img) {
              wx.getFileInfo({
                filePath: img,
                success: function (res) {
                  console.log('压缩后:' + res.size / 1024 + 'kb')
                }
              })
              that.setData({
                FilePaths: [img]
              })
              that.transferpic();
            })
          } else {
            that.setData({
              FilePaths: res.tempFilePaths
            })
            that.transferpic();
          }
        },
        complete: function (res) {
          that.setData({
            isHandling: false
          })
        }
      })
    },
    

    引用的 util.js

    /**
     * 获取小于限制大小的Image, limitSize默认为100KB,递归调用。
     */
    function getLessLimitSizeImage(canvasId, imagePath, limitSize = 500, drawWidth, callBack) {
      imageSizeIsLessLimitSize(imagePath, limitSize,
        (lessRes) => {
          callBack(imagePath);
        },
        (moreRes) => {
          wx.getImageInfo({
            src: imagePath,
            success: function (imageInfo) {
              var maxSide = Math.max(imageInfo.width, imageInfo.height);
              //画板的宽高默认是windowWidth * 2
              var windowW = drawWidth;
              var scale = 1;
              if (maxSide > windowW) {
                scale = windowW / maxSide;
              }
              var imageW = Math.trunc(imageInfo.width * scale);
              var imageH = Math.trunc(imageInfo.height * scale);
              getCanvasImage(canvasId, imagePath, imageW, imageH,
                (pressImgPath) => {
                  getLessLimitSizeImage(canvasId, pressImgPath, limitSize, drawWidth * 0.95, callBack);
                }
              );
            }
          })
        }
      )
    }
    // 判断图片大小是否满足需求
    function imageSizeIsLessLimitSize(imagePath, limitSize, lessCallBack, moreCallBack) {
      wx.getFileInfo({
        filePath: imagePath,
        success(res) {
          if (res.size > 1024 * limitSize) {
            moreCallBack();
          } else {
            lessCallBack();
          }
        }
      })
    };
    /**
     * 获取画布图片 
     */
    // 利用cavas进行压缩  每次压缩都需要ctx.draw()  wx.canvasToTempFilePath()连用
    function getCanvasImage(canvasId, imagePath, imageW, imageH, getImgsuccess) {
      const ctx = wx.createCanvasContext(canvasId);
      ctx.drawImage(imagePath, 0, 0, imageW, imageH);
      ctx.draw(false, setTimeout(function () { // 一定要加定时器,因为ctx.draw()应用到canvas是有个时间的
        wx.canvasToTempFilePath({
          canvasId: canvasId,
          x: 0,
          y: 0,
          width: imageW,
          height: imageH,
          quality: 1,
          success: function (res) {
            getImgsuccess(res.tempFilePath);
          },
        });
      }, 200));
    };
    // 图片转basee64    io操作 使用异步方式
    function getBase64(img) {
      return new Promise(function (resolve, reject) {
        const FSM = wx.getFileSystemManager();
        FSM.readFile({
          filePath: img,
          encoding: 'base64',
          success(data) {
            resolve(data)
          }
        })
      })
    }
    

    H5页面图片压缩

    HTML

    <div class="lead small text-center icon_title" >
        <label for="file_hand" >手持身份证照</label>
    </div>
    <input type="file" id="file_hand" name="hand" class="hide" 
        data-name="hand" data-loading="false" accept="image/*" @change="upload"/>
    <canvas style="visibility: hidden;position:absolute; z-index: -1;left: -10000px;top:-10000px" id="myCanvas"></canvas>
    

    JS

    upload: function(event) =>{
      let name = event.target.dataset.name;
      let file = event.target.files[0];
      let type = file.type;
      if (type.search('image') === -1){
        console.log('文件格式错误,只支持图片格式')
        return;
      } else {
        let size = file.size;
        if (size > 7168 * 1024) {   // 7MB
          console.log('文件大小超出限制,只支持小于7MB')
          return;
        } else if (size > 500 * 1024){
          // 大于 500kb 小于 7MB 的图片把它压缩到 500kb 再上传
          this.compressImage(file,name);
          return
        }
        let form = new FormData();
        form.append("file",file);
        form.append("openId",vue.openId);
        // 上传图片
        vue.$http.post("/wechat/remote-api/workers/image/upload",form,{
          headers:{'Content-Type':'multipart/form-data'}
        }).then((res) => {
          if (res.data && res.data.success && res.data.data){
            let data = res.data.data;
            //处理对应的返回信息
          }else {
            console.log("服务器异常,"+res.data.description+"!");
          }
        }).catch((res) => {
          console.log('服务器异常,请稍后再试!')
        })
      }
    },
    compressImage: function(file,name){
      let  reader=new FileReader();
      reader.readAsDataURL(file);
      reader.onload=function () {
        let content=this.result; //图片的src,base64格式
        let img = new Image();
        img.src=content;
        img.onload=function (){ //图片加载完毕
          let coefficient = 0;// 压缩系数
          if (file.size > 6291456) {
            coefficient = 0.06
          } else if (file.size > 5242880) {
            coefficient = 0.07
          } else  if (file.size > 4194304) {
            coefficient = 0.09
          } else if (file.size > 3145728) {
            coefficient = 0.12
          } else if (file.size > 2097152) {
            coefficient = 0.16
          } else if (file.size > 1048576) {
            coefficient = 0.5
          } else {
            coefficient = 0.7
          }
          this.compressEvent(img,coefficient,(dataURL)=> {
            this.uploadImg(dataURL,file,name);
          })
        }
      };
    },
    // 把图片绘制到canvas上去
    compressEvent: function(img,coefficient,callback){
      let canvas=document.getElementById('myCanvas');
      let ctx=canvas.getContext('2d');
      let initSize=img.src.length;
      let width=img.width;
      let height=img.height;
      canvas.width = width;
      canvas.height = height;
      ctx.drawImage(img, 0, 0, width, height);
      let dataURL = canvas.toDataURL("image/jpeg", coefficient);
      callback ? callback(dataURL) : null; //调用回调函数
    },
    // dataURL转换为Bold对象或File对象
    dataURItoBlob(dataurl,filename){   //dataurl是base64格式
      let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
      bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
      while(n--){
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], filename, {type:mime});
    },
    // 将Bold对象转换成formData对象,并提交
    uploadImg:function (dataURL,file,name){
        let _file = vue.dataURItoBlob(dataURL,file.name);
        console.log(_file)
        if (_file.size > 500 * 1024){
            // 大于 500kb 小于 7MB 的图片把它压缩到 500kb 再上传
            return console.log("图片压缩失败!请换张图片再试!");
        }
        let form = new FormData();
        form.append("file",_file);
        form.append("openId",vue.openId);
        vue.$http.post("/wechat/remote-api/workers/image/upload",form,{
            headers:{'Content-Type':'multipart/form-data'}
        }).then((res) => {
          if (res.data && res.data.success && res.data.data){
            let data = res.data.data;
            //处理对应的返回信息
          }else {
            console.log("服务器异常,"+res.data.description+"!");
          }
        }).catch((res) => {
          console.log('服务器异常,请稍后再试!')
        })
    }
    

    相关文章

      网友评论

          本文标题:原生JS上传并压缩图片-实例

          本文链接:https://www.haomeiwen.com/subject/qvchuhtx.html