h5调取拍照小功能

481 阅读2分钟

背景

在很多业务场景中,经常会让用户拍照上传图片。随着现在的人生活质量越来预高,手机的配置也非常好。这就导致用手机拍出来的照片都是高清的普遍都是M级别以上的。这个时候如果直接上传原图的话,对本身的项目是一种损耗,为了减少不必要的损耗那么我们只能将上传的照片进行压缩。

拍照实现

  1. 使用原生input调用拍照功能 下面这串代码是只允许调用拍照的,去掉了从相册中选择图片的功能。
<div class="ex-take-picture__content-button ex-take-picture__button">
        <label for="fileInpBtn">立即拍照</label>
        <input id="fileInpBtn" type="file" capture="camera" style="display: none;"  @change="imgup" accept="image/*">
      </div>

2 获取拍照的文件信息 这里的preloadAll方法只是一个加载图片对象的方法,其实可以不用的 因为在压缩图片的方法里面已经有加载过了,有优化的空间。

async imgup (e) {
  let file = e.target.files[0]
  this.localId = window.URL.createObjectURL(file)
  this.imgData = await this.compressImg(file) // 压缩图片
  // 这里是加载图片
  preloadAll({
    links: [this.localId],
    type: 'image'
  }).then(res => {
    const img = res[0].resource
    // 根据宽度高度比例设置图片该固定哪个一边 另一边自适应 这样图片不会变形
    const percentage = img.width / img.height
    if (percentage >= 1) {
      // 横屏
      this.previewImgStyle = {
        backgroundImage: `url('${this.localId}')`
      }
      this.previewImgClass = 'bgYCenter'
    } else {
      // 竖屏
      this.previewImgStyle = {
        backgroundImage: `url('${this.localId}')`
      }
      this.previewImgClass = 'bgXCenter'
    }
  })
}

压缩图片

加载图片完成后获取图片的原始宽度高度然后固定宽度或者高度,然后等比例缩放这是压缩第一步;如果这样压缩的程度还不够,那么可以再将图片放到canvas里面使用canvas的toBlob或者toDataURL进行第二次压缩。

compressImg (fileObject) {
  return new Promise(resolve => {
    const MAX_WH = 800
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    let img = new Image()
    img.src = window.URL.createObjectURL(fileObject)
    img.onload = function () {
      if (img.height > MAX_WH) {
        // 宽度等比例缩放 *=
        img.width *= MAX_WH / img.height
        img.height = MAX_WH
      }
      if (img.width > MAX_WH) {
        // 宽度等比例缩放 *=
        img.height *= MAX_WH / img.width
        img.width = MAX_WH
      }
      canvas.width = img.width
      canvas.height = img.height
      ctx.clearRect(0, 0, img.width, img.height)
      ctx.drawImage(img, 0, 0, img.width, img.height)
      // const base64 = canvas.toDataURL('image/jpeg', 0.7)
      // newImgList.push(base64)
      // if (newImgList.length === 3) resolve(newImgList)
      canvas.toBlob(function (blob) {
        // const url = URL.createObjectURL(blob)
        // const file = new window.File([url], fileObject.name, { type: fileObject.type })
        // URL.revokeObjectURL(url)
        resolve(blob)
      }, 'image/jpeg', 0.7)
    }
  })
}

其实通过上面的代码实现,我们就有很多可以自己去玩的地方,比如canvas将图片转换成各种文件流或者文件格式的功能。