dom-to-image 将vue中未显示的组件转成图片, 并上传

2023-11-01

一、dom-to-image基本使用

npm地址

import domtoimage from 'dom-to-image'

export function dom2img(node) {
  return domtoimage.toPng(node, { cacheBust: true })
    .then(function(dataUrl) {
      var img = new Image();
      img.src = dataUrl;
      document.body.appendChild(img);
      return dataUrl
    })
    .catch(function(error) {
      console.error('oops, dom2img went wrong!', error);
    });
}

// 实现将dom转成图片
// node: this.$refs.id 或者 document.getElementById('id')
dom2img(node).then(img => {
 // 处理base64格式的img
}

可以添加参数 , 比如控制大小,修改样式

domtoimage.toJpeg(node, {
   width: 330,
    height: 155,
    cacheBust: true,
    style: {
      margin: 0,
      background: '#fff',
    }
  })

二、注意点

dom-to-image
将dom转图片有个前提,就是一定要在文档中显示,任何样式导致不显示都导致无法生成图片,比如:visibility:hidden,display: none;
宽高不能是100%,否则也是转换失败

如果是动态引入的组件转换,要保证组件没有需要异步加载的部分,比如一些背景图是请求接口的, 只能在页面显示后,通过$refs来获取dom,动态引入不知道什么时候加载完成的

toPng 要去掉dom样式中的margin,否则切图出来的会有被截断的问题

三、生成的图片上传至服务器

平时上传图片主要是用到<input>元素, 用户选择的文件最终是File对象,所以,我们将生成的图片转成File对象,然后通过formData上传即可。
这里主要用png格式和blob格式举例

1、base64 转 File 格式

function base64toFile(dataUrl, fileName = 'image') {
  let arr = dataUrl.split(',')
  let mime = arr[0].match(/:(.*?);/)[1]

  let bstr = window.atob(arr[1]) // base64编码
  let n = bstr.length
  let u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n) // unicode 编码
  }
  return new File([u8arr], `${fileName}.png`, {
    type: mime
  })
}

2、blob 转 File 格式

File继承自Blob,是特殊类型的 Blob。

function blobtoFile(blob, fileName = 'image') {
  const file = new File([blob], fileName, {
    type: blob.type
  })
  return file
}

3、在页面展示生成的图片

function showImg(dataUrl) {
  var img = new Image()
  img.src = dataUrl
  document.body.appendChild(img)
}

4、最终dom转图片函数

// XXX domtoimage 转图片有个前提,一定要在文档中显示,任何样式导致不显示都导致无法生成图片
// toPng(node, {width: 330, height: 155, quality: 0.95 }), 可以添加参数
// toPng 要去掉dom样式中的margin, 否则切图会有问题
import domtoimage from 'dom-to-image'
export function dom2img(node, fnType = 'toPng') {
  return domtoimage[fnType](node, {
      cacheBust: true
    })
    .then(function(dataUrl) {
      // png
      if (fnType === 'toPng') {
        // 显示图片
        showImg(dataUrl)
        // 生成file格式用于上传
        return base64toFile(dataUrl)
      }

      // blob 
      if (fnType === 'toBlob') {
        // 显示图片: 通过Blob Url,blob://模式类似于http://, 
        const blobUrl = URL.createObjectURL(dataUrl)
        showImg(blobUrl)
        // 防止内存溢出,要手动释放
        setTimeout(() => {
          URL.revokeObjectURL(blobUrl)
        }, 200)

        // 生成file格式用于上传, 这个有问题,接口报错-- FIXME
        return blobtoFile(dataUrl)
      }

      return dataUrl
    })
    .catch(function(error) {
      console.error('oops, dom2img went wrong!', error)
    })
}

5、上传图片

function uploadImgToBoot(imgFile) {
  const formData = new FormData();
  formData.append('file', imgFile)
  return uploadZhImg(formData).then(res => {
    return res
  })
}

6、问题未解决

blob转File后,上传图片接口报错, 未找到原因


四、vue实现将不显示的组件转成图片,而组件之间出现循环引用

在这里插入图片描述

1、首先在html中放一个占位div,用于渲染dom

 <!-- 用于挂载占位,不需要显示-->
 <div id="hideNode" class="show-in-back"></div>
 
 // 不能使用visibility:hidden 或者 display:none, 会导致dom转换失败
 .show-in-back {
   position: absolute;
   top: 0;
   z-index: -1000;
 }

2、这里使用动态引入避免组件死循环:

// XXX 可以使用这种动态引入的前提是: 组件没有需要异步加载的部分,比如合集中的背景图是请求接口的, 只能通过$refs来
// 动态引入组件,避免组件之间出现循环引入,当出现死循环时,import的结果为undefined
const ApplyCard = () => import('@/views/apply/components/ApplyCard.vue')

这里有两种vue的引入方式: 模板编译和runtime模式

// 默认runtime模式,指向了"dist/vue.runtime.common.js"位置
import Vue from 'vue'
// 下面引入采用的是模板编译引入链接
// import Vue from 'vue/dist/vue.esm.js'

3、挂载点内容会被vue组件覆盖,所以每次要新建一个挂载点内容,设置id="toImg"

// 新建挂载点内容
const node = document.getElementById('hideNode')
node.innerHTML = '<div id="toImg"></div>'

4、利用vue动态构建组件,并挂载到id="toImg"

ApplyCard().then(res => {
  // 获取vue组件
  const temp = res.default

  const Card = Vue.extend(temp)
	
  // 动态挂载相应的组件
  // 获取组件,这里采用的是模板编译 
  // -- 存在问题:上面更换了vue,导致在组件没有显示的页面,渲染组件会报错: element组件以及自定义全局组件没有引入
  // const vueComponent = new Card({
  //   el: '#toImg',
  //   propsData: {
  //     info: {}
  //   }
  // })
  
  // 动态挂载相应的组件改成render函数渲染
  const vueComponent = new Vue({
    el: '#toImg',
    render: function (h) {
      return <Card info={info}></Card>
    }
  })

  // 等加载完之后,获取dom
  vueComponent.$nextTick(() => {
    const node = vueComponent.$el
    // 生成图片并分享招乎
    dom2img(node).then(img => {
      // 处理base64格式的img
    })
  })
})
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

dom-to-image 将vue中未显示的组件转成图片, 并上传 的相关文章

随机推荐

  • 【问题解决】partially initialized module ‘cv2‘ has no attribute

    使用 MMOCR 时报错 partially initialized module cv2 has no attribute 可能是 opencv 的版本问题 也可能是 opencv 和当前环境不能完全匹配的问题 可以使用下面的方法重新安装
  • 分享一个 ChatGPT可免费使用的AI助手

    现在 多种行业都已经开始广泛地采用聊天机器人ChatGPT 有一个与之相关的国内免费网站可以供大家使用 多御浏览器 这是一款安全快速 高效稳定的浏览器 该网站客户端软件中 有很多实用工具 其中之一就是当下非常流行的 ChatGPT 这对于开
  • python 更换pip安装源

    pip源 默认从国外源安装 安装速度比较慢 现在我们指定国内源安装源 阿里源 豆瓣源 Ubuntu源 1 指令配置源 pip3 install xlrd i https pypi tuna tsinghua edu cn simple 2
  • Qt - QSetting的使用

    欢迎转载 请注明出处 https blog csdn net qq 39453936 spm 1010 2135 3001 5343 原文链接 https blog csdn net qq 39453936 article details
  • Allegro快捷键

    env文件替换路径C Cadence SPB 16 6 share pcb text
  • mac启动pg数据库失败 “Is another postmaster (PID 370) running in data directory“

    解决办法 进入目录 usr local var postgres 删除文件 postmaster pid 启动pg命令 pg ctl D usr local var postgres l usr local var postgres ser
  • 挖矿病毒的特点

    挖矿病毒的特点 1 文件 定时任务删除失败 文件只读属性保护 2 文件 定时任务删完又出现 系统文件替换 下载进程残留 3 病毒进程刚刚删完又被拉起 恶意进程守护 4 主机严重卡顿但找不到挖矿进程 系统命令劫持 5 主机杀干净后一段时间又出
  • 【云原生之kubernetes】在kubernetes集群下的映射外部服务—Eendpoint

    云原生之kubernetes 在kubernetes集群下的映射外部服务 Eendpoint 一 Eendpoint介绍 1 endpoint简介 2 endpoint的使用 二 检查本地k8s状态 1 检查工作节点状态 2 检查系统pod
  • Modelsim、Matlab在远程桌面下打开的异常及处理

    此方法可以解决远程桌面下启动MATLAB时的License Manager Error 103错误 也能够解决远程桌面下启动modelsim的错误 方法如下 1 打开C Program Files MATLAB R2015b license
  • kafka基础介绍

    目录 前言 一 kafka架构 1 kafka基础架构 2 kafka多副本架构 二 kafka基础概念 1 produce 2 Consumer 3 Broker 4 Topic 5 Partition 6 Replicas 7 Offs
  • C++数据结构X篇_12_树的基本概念和存储

    学习二叉树之前先学习树的概念 文章目录 1 树的基本概念 1 1 树的定义 1 2 树的特点 1 3 若干术语 2 树的表示法 2 1 图形表示法 2 2 广义表表示法 3 树的存储 3 1 双亲表示法 保存父节点关系 3 2 孩子表示法
  • 伴随矩阵的特征值和特征向量

    结 论 伴 随 矩 阵 的 特
  • winsock

    今天上午学习了 winsock的使用的过程 现将学习的收获总结如下 Winsock的属性 1 Localport 设定本机的端口号 端口号从0 65536 其中1024一下一般为专用的端口 如21为ftp默认端口 80为http默认端口 2
  • 关于对CSDN这些技术博客类网站的一些个人看法

    今天这篇文章其实是自己的一个分享与感悟 分享一下自己从技术小白到有点小实力的这个过程中对自己帮助的一些技术博客类网站的看法 关于我为什么会想写这么一篇文章呢 起因是我有一次查CSDN网站时候 看到了一篇文章 第一眼看到这篇文章的时候我觉得首
  • Java多线程 - - -线程安全问题

    Java 多线程学习笔记 二 线程安全问题的出现 当一个进程中的多个线程共享资源或数据的时候 就会出现安全隐患 例如 三个售票窗口同时售票 如果没有进行线程安全的处理 则会出现重票 错票等线程安全问题 package com fff 实现R
  • Modbus协议介绍

    Modbus协议介绍 简介 Modbus是一种串行通信协议 是Modicon公司 现在的施耐德电气Schneider Electric 于 1979年为使用可编程逻辑控制器 PLC 通信而发表 Modbus 已经成为工业领域通信协议的业界标
  • JDBC数据库驱动的下载、安装与连接

    1 常用的数据库驱动下载 使用JDBC操作数据库 需要使用数据库厂商提供的驱动程序 通过驱动程序可以与数据库进行交互 1 1 常用的数据库厂商驱动下载地址 1 1 1 MySQL数据库 https dev mysql com downloa
  • Pytorch基于DDPM+InceptionNext+数据增强的图像分类(一)

    项目简介 本项目旨在通过使用深度学习技术实现对图像进行分类 我采用了DDPM Deep Dynamic Probabilistic Modeling 和InceptionNext两个模型的结合 以提高图像分类的准确性和性能 同时 我还使用了
  • 拷贝构造函数和赋值构造函数声明为私有的作用

    转载 http blog csdn net rabbit729 article details 4000500 每个类只有一个赋值函数 由于并非所有的对象都会使用拷贝构造函数和赋值函数 程序员可能对这两个函数有些轻视 请先记住以下的警告 在
  • dom-to-image 将vue中未显示的组件转成图片, 并上传

    目录 一 dom to image基本使用 二 注意点 三 生成的图片上传至服务器 1 base64 转 File 格式 2 blob 转 File 格式 3 在页面展示生成的图片 4 最终dom转图片函数 5 上传图片 6 问题未解决 四