美文网首页
原生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上传并压缩图片-实例

    微信小程序和H5页面的实例 小程序 wxml js 引用的 util.js H5页面图片压缩 HTML JS

  • 利用html5 完成图片上传、预览、删除

    接上次 html js 压缩图片函数 预览图片删除 css,主要改了h5图片上传的样式,还有预...

  • js图片压缩预览

    图片压缩预览(具体上传请看另外一篇文章,讲解的更详细图片压缩上传) html结构 js代码 css代码 欢迎访问我...

  • js图片压缩上传

    前端有时候会遇到图片太大,预览过慢和无法传给后台的困境,另外还浪费流量。在这里给大家推荐一款配合jQuery运行的...

  • js压缩上传图片

    一、html部分 二、js部分1.获取图片文件 2.利用canvas压缩图片,根据画布大小和图像质量压缩 3.通过...

  • input上传图片并压缩(vue,前端,js)

    大家好,我是云皓,话不多说,直入正题 1,获取input上传file文件2,转化为base64文件3,压缩4,转换...

  • 微信小程序上传图片压缩

    上传图片时图片过大,接口请求速度会很慢,利用canvas对图片进行压缩 wxml文件: js文件:

  • iOS 网络上传图片

    上传图片 构造参数(NSArray *)files 上传图片—压缩 压缩到小于(...

  • iPic for Mac(图床神器) v1.7.0中文免费版

    上传图片相关设置 上传前压缩图片 可以在 iPic 的 偏好设置 中开启「上传前压缩图片」选项,目前支持压缩的图片...

  • 前端图片压缩上传

    (纯js的质量压缩,非长宽压缩) 此demo为大于1M对图片进行压缩上传 若小于1M则原图上传,可以根据自己实际需...

网友评论

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

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