Web截图

注意出现如下报错,是图片或者视频跨域了,需要对静态资源进行反向代理,并且需要在服务器环境下运行

Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

截取图片

/**
 * @Author ZhenYuTsai
 * @Description 截取图片
 * @Param {Sting} id 需要截取的容器的id
 * @Param {Sting} type 返回的文件类型file/base64
 * @Param {Boolean} boolean 是否需要显示预览图片默认值为false
 * @Return {Object} file 返回截取图片的base64/file对象
 * @Return {Sting} url 返回截取图片预览地址,base64类型返回null
 */
const interceptElement = (id, type='file', boolean=false) => {
  // 1、需要截取视频的容
  const v = document.getElementById(id)
  const c = v.getClientRects()
  // 2、创建canvas容器
  const cas = document.createElement('canvas')
  // 3、设置canvas容器尺寸
  cas.width = c[0].width
  cas.height = c[0].height

  // 4、转换为2D视图,270/135 截取容器的大小
  const ctx = cas.getContext('2d')
  ctx.drawImage(v, 0, 0, cas.width, cas.height)
  // 5、将canvas转换成base64
  const base64 = cas.toDataURL('image/png')
  // 判断文件类型
  if(type==='file'){
    const file = base64ToFile(base64)
    return new Promise((resolve)=>{
      const url = URL.createObjectURL(file)
      if(boolean){
        showImg(url)
      }
      resolve({file:file,url:url})
    })
  }  else {
    // 调用base64图片压缩
    return new Promise((resolve)=>{
      compressImage(base64).then((url)=>{
        if(boolean){
          showImg(url)
        }
        // 返回图片base64
        resolve({file:url,url:null})
      })
    })
  }
}

图片压缩

/**
 * @Author ZhenYuTsai
 * @Description 压缩base64图片
 * @Param {String} base64 需要压缩图片的base64
 * @Return {String} String 返回压缩后的图片base64
 */
const compressImage = (base64) => {
  return new Promise((resolve)=>{
    const img = new Image() 
    img.setAttribute('crossOrigin','anonymous')
    img.src = base64
    img.onload = ()=>{
      const w = img.width
      const h = img.height
      // 默认图片质量为0.92
      const quality = 0.92 
      // 生成canvas
      const canvas = document.createElement('canvas')
      // 获取上下文
      const ctx = canvas.getContext('2d')
      // 创建属性节点
      const anw = document.createAttribute('width')
      anw.nodeValue = w
      const anh = document.createAttribute('height')
      anh.nodeValue = h
      canvas.setAttributeNode(anw)
      canvas.setAttributeNode(anh) // 铺底色 PNG转JPEG时透明区域会变黑色
      ctx.fillStyle = '#fff'
      ctx.fillRect(0, 0, w, h)
      ctx.drawImage(img, 0, 0, w, h)
      // quality值越小,所绘制出的图像越模糊
      const base64 = canvas.toDataURL('image/jpeg', quality) 
      resolve(base64)
    }
  })
}

base64转换为file对象

/**
 * @Author ZhenYuTsai
 * @Description base64转换为file对象
 * @Param {String} data base64数据
 * @Return {Object} file file对象
 */
const base64ToFile = (data) => {
  const binary = atob(data.split(',')[1])
  const mime = data.split(',')[0].match(/:(.*?);/)[1]
  let array = []
  for (let i = 0; i < binary.length; i++) {
    array.push(binary.charCodeAt(i))
  }
  const fileData = new Blob([new Uint8Array(array)], {type: mime})
  const file = new File([fileData], `${new Date().getTime()}.png`, { type: mime })
  return file
}

新建页面预览图片

/**
 * @Author ZhenYuTsai
 * @Description 新建页面预览图片
 * @Param {String} url 文件地址
 */
const showImg = (url) => {
  const img = new Image()
  img.src = url
  const newWin = window.open('', '_blank')
  newWin.document.write(img.outerHTML)
  newWin.document.title = '预览图片'
  newWin.document.close()
}