个人记录1-前端页面截屏保存为图片,并将base64转为file类型上传保存

115 阅读2分钟

# html2canvas (有样式问题,性能也不好)

  • 简介

html2canvas 是一个 HTML 渲染器。该脚本允许你直接在用户浏览器截取页面或部分网页的“屏幕截屏”,屏幕截图是基于 DOM,因此生成的图片并不一定 100% 一致,因为它没有制作实际的屏幕截图,而是根据页面上可用的信息构建屏幕截图。
html2canvas中文文档

  • 安装

npm install html2canvas
  • 导入

import html2canvas from "html2canvas";
  • 使用

/**
 * @func takeScreenshotsToImages
 * @desc 截屏并保存为图片
 * @param {String} className 需要截屏的元素类名 默认截取body
 * @param {Number} h 截图高度 非必传,指定截屏高度
 * @param {Number} w 截图宽度 非必传,指定截屏宽度
 */
takeScreenshotsToImages(className, h, w) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const element = className ? document.querySelector(className) : document.body
      const width = w || element.offsetWidth
      const height = h || element.scrollHeight
      html2canvas(element, {
        backgroundColor: "#ffffff",
        scrollX: element.offsetWidth,
        scrollY: element.scrollHeight,
        width,
        height,
        windowWidth: width,
        windowHeight: height,
        scale: 3, // 放大倍数,避免模糊
        useCORS: true, // 允许跨域,页面中的图片也可以截图保存
      })
        .then(function (canvas) {
          const url = canvas.toDataURL("image/png")
          resolve(url)
        })
        .catch((e) => {
          reject(e)
        })
    }, 200)
  })
},

# 使用封装好的方法 takeScreenshotsToImages

// 截屏保存为图片
async saveAsImage() {
  // 不需要截取全部内容,指定高度
  const h = document.querySelector('.main-body_content_bg').clientHeight
  // 调用封装到 utils.js 中的 takeScreenshotsToImages 方法
  const url = await utils.takeScreenshotsToImages('#container', h)
  if (url) {
    // 将 base64 转为 Blob
    function dataURLtoBlob(dataurl) {
      const arr = dataurl.split(',')
      const mime = arr[0].match(/:(.*?);/)[1]
      const bstr = atob(arr[1])
      let n = bstr.length
      const u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new Blob([u8arr], { type: mime })
    }
    const blob = dataURLtoBlob(url)
    const file = new File([blob], 'dashboard.png', { type: blob.type })

    const formData = new FormData()
    formData.append('file', file)
    // 上传图片
    const { RetCode, RetObject, RetMessage } = await api_uploadImage(formData)
    if (RetCode === 0) {
      console.log('上传成功!', 'RetMessage===>' + RetMessage)
    } else {
      this.$message.error(RetMessage || '上传失败,请重试')
    }
  }
},

# modern-screenshot

  • 安装
npm i modern-screenshot
或
yarn add modern-screenshot
  • 使用 (官网例子)
import { domToPng } from 'modern-screenshot'

domToPng(document.querySelector('#app')).then((dataUrl) => {
  const link = document.createElement('a')
  link.download = 'screenshot.png'
  link.href = dataUrl
  link.click()
})
  • 支持方式

DOM to dataURL

  1. domToPng
  2. domToSvg
  3. domToJpeg
  4. domToWebp
  5. domToDataUrl

DOM to data

  1. domToBlob
  2. domToPixel

DOM to HTMLElement

  1. domToForeignObjectSvg
  2. domToImage
  3. domToCanvas

# 更改 takeScreenshotsToImages 方法

takeScreenshotsToImages(className, h, w) {
    return new Promise((resolve, reject) => {
      const element = className
        ? document.querySelector(className)
        : document.body;
      const width = w || element.offsetWidth;
      const height = h || element.scrollHeight;
      const option = {
        backgroundColor: "#ffffff",
        scrollX: element.offsetWidth,
        scrollY: element.scrollHeight,
        width,
        height,
        windowWidth: width,
        windowHeight: height,
        scale: 3, // 放大倍数,避免模糊
        useCORS: true, // 允许跨域
      };
      domToPng(element, option)
        .then((dataUrl) => {
          resolve(dataUrl);
        })
        .catch((e) => {
          reject(e);
        });
    });
  },