记录 html2canvas 生成海报 ### 处理生成图片背景不清晰问题 ###

背景 : next.js 根据不同数据生成不同海报 支持 长按保存图片

处理生成图片背景不清晰问题

2023.03.08 更新
使用 html2canvas 发现生成图片 背景不清晰 ,尝试各种放大、缩小、重绘、 生成图片质量改变不大。
最后问题是 css 引用背景图片造成的。
解决方法: 不使用背景图片写样式, 不使用背景图片写样式, 不使用背景图片写样式, 将背景图 转为<img/> 定位到需要的位置 生成的图片非常清晰

方案一: 使用canvas 画

	 难点: 内容较多 确定元素位置 太麻烦  性能消耗大

方案二: html2canvas.js

在这里插入图片描述

	难点:引入方式 (ssr 项目中  import  引入 得到 undefined )
			  渐变色 截图失真
			  清晰度不够
			  生成图片展示带有白底 (给展示盒子 加 overflow: hidden)

解决 引入方式

发现: 
	在本地启动项目没有问题
	import html2canvas from 'html2canvas';
	打包后再 在服务器构建 就提示 服务器错误 500 页面404 
	然后排除到是 html2canvas 为undefind 导致页面报错
处理:
	1、 建一个资源文件 在同级目录引入 (本地可以使用、无法通过eslint 所以不知道服务端效果)
	2、 按需引入 类似懒加载 只有执行到这里了 才会引入 
		import('html2canvas').then(
	      html2canvas =>
	        html2canvas(shareContent, opts).then(function (canvas) {
	          var context = canvas.getContext('2d')
	          // 【重要】关闭抗锯齿
	          context.mozImageSmoothingEnabled = false
	          context.webkitImageSmoothingEnabled = false
	          context.msImageSmoothingEnabled = false
	          context.imageSmoothingEnabled = false
	          const url = canvas.toDataURL('image/png', 1)// 图片地址
	        }).catch(e => { console('load failed') })
    	) 

渐变色 截图失真 (在第二中方式中 清晰度修改效果一般 记的设置canvas 的宽高)

展示图片的方式

  /**
   * 方案一
   *this.generate()
   * 缺点: 无法兼容 背景渐变
   * */
  generate () {
    const _this = this
    import('html2canvas').then(
      html2canvas => {
      // this.defaultHtml 生成图片最外层盒子
        html2canvas(this.defaultHtml,
          {
            width: this.defaultHtml.clientWidth,
            height: this.defaultHtml.clientHeight,
            scale: 1,
            useCORS: true,
            allowTaint: false
          }).then(function (canvas) {
          const url = canvas.toDataURL('image/png', 1)// 图片地址 base64
          _this.setState({
            urlimg: url
          })
          _this.setState({ isShow: false })
        })
      }
    )
  }

 /**
   * 方案二
   *this.convert2canvas()
   * 缺点: 兼容背景渐变 创建新的canvas 画出二倍图
   * */
     dprFnc () { // 获取设备dpi
    if (window.devicePixelRatio && window.devicePixelRatio > 1) {
      this.setState({ scale: window.devicePixelRatio })
      return window.devicePixelRatio
    }
    return 1
  }
  
  convert2canvas () {
    const _this = this
    var shareContent = this.defaultHtml// 需要截图的包裹的(原生的)DOM 对象
    var width = shareContent.offsetWidth // 获取dom 宽度
    var height = shareContent.offsetHeight // 获取dom 高度
    var canvas =  this.canvas // 创建一个canvas节点 !!!!!注意这里  这个就是创建的canvas!!!!!!
    var scale = 2 // 定义任意放大倍数 支持小数
    canvas.width = width * scale // 定义canvas 宽度 * 缩放
    canvas.height = height * scale // 定义canvas高度 *缩放
    canvas.getContext('2d').scale(scale, scale) // 获取context,设置scale
    var opts = {
      scale: scale, // 添加的scale 参数
      canvas: canvas, // 自定义 canvas
      // logging: true, //日志开关,便于查看html2canvas的内部执行流程
      width: width, // dom 原始宽度
      height: height,
      useCORS: true // 【重要】开启跨域配置
    }
    import('html2canvas').then(
      html2canvas =>
        html2canvas(shareContent, opts).then(function (canvas) {
          var context = canvas.getContext('2d')
          // 【重要】关闭抗锯齿
          context.mozImageSmoothingEnabled = false
          context.webkitImageSmoothingEnabled = false
          context.msImageSmoothingEnabled = false
          context.imageSmoothingEnabled = false
          const url = canvas.toDataURL('image/png', 1)// 图片地址
          _this.setState({ urlimg: url })
          _this.setState({ isShow: false })
        }).catch(e => { console('load failed') })
    )
  }

	<canvas className="hide"
         ref={ele => { this.canvas = ele }}
         width={this.state.width * 2} height={ this.state.height * 2}
    ></canvas>

提示

在Mac中开发 会发现 生成的图片 比html 生成的图片中 字体会偏下
效果如下 : 
出现问题原因:由于字体不同  ,window 上没有出现下沉情况 手机端也没有出现
处理方式: 引入字体 (字体文件大 不建议 ) 
		如果非要加入 可以那就配置文件压缩 vue项目 试过 ~~
		react ssr的还没试过 不确定怎么操作  

在这里插入图片描述

ios 13+ 版本失效问题

首先移除 html2canvas 【npm uninstall html2canvas】
然后安装指定版本 【npm install --save html2canvas@1.0.0-rc.4】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值