zoukankan      html  css  js  c++  java
  • html2canvas的踩坑之路

    html2canvas的踩坑之路

    前言

    早有耳闻这个html2canvas比较坑,但无奈于产品需求的压迫,必须实现html转图片的功能,自此走上了填坑之路,好在最后的效果还算令人满意,这才没有误了产品上线周期.

    html2canvas介绍

    html2canvas的详细介绍可以点击这里查看,其实简单来说就是通过canvasHTML生成的DOM节点绘制到画布上,再可以通过自己的需求转换成图片.所以官方文档也说了,最后生成的效果不是100%相同的,这一点大家要有心理准备,无论怎样,一点点小瑕疵是肯定有的。

    兼容性

    PS:微信浏览器使用也是没有问题的哦

    使用html2canvas

    使用也是十分简单,官网写的很清楚戳这里

    踩坑过程

    生成的图片里面为什么缺失微信头像或其他图片?

    其实涉及到的就是跨域问题,即便是canvas的画布中对于图片的域也是有要求的,那我们应该怎么解决呢?

    1. html2canvas配置项中配置 allowTaint:true 或 useCORS:true(二者不可共同使用)
    2. img标签增加 crossOrigin='anonymous'
    3. 图片服务器配置Access-Control-Allow-Origin 或使用代理

    其中第三步是最重要的,不设置则前两步设置了也无效。

    服务器需要配置Access-Control-Allow-Origin信息,如PHP添加响应头信息,*通配符表示允许任意域名:

    header("Access-Control-Allow-Origin: *");
    

    或者指定域名:

    header("Access-Control-Allow-Origin: www.zhangxinxu.com");
    

    但如果不想麻烦后端的人员,那我们前端怎么跨域呢? 那就可以使用代理插件,如: html2canvas-proxy-nodejs 或者是 superagent,我是使用superagent,贴一下示例代码:

    const request = require('superagent') // 导入
    const proxHost = 'https://thirdwx.qlogo.cn' // 指定跨域图片的地址
    app.use('/proxy', function (req, res, next) {
      let urlPath = req.url
      console.log('urlPath', urlPath)
      urlPath = decodeURI(urlPath)
      if (!urlPath) {
        console.log('urlPath is null')
        return next()
      }
      console.log('proxy-request: /proxy->' + `${proxHost}${urlPath}`)
      const reqStream = request.get(`${proxHost}${urlPath}`)
      reqStream.on('error', function (err) {
        console.log('error', err)
      })
      console.log('------reqStream----')
      return reqStream.pipe(res)
    })
    

    那么最终我在页面中的图片的srchttps://thirdwx.qlogo.cn/xxx 要更改为/proxy/xxx 效果图如下:

    2.生成的图片模糊不清且有锯齿瑕疵怎么办?

    大部分找到的结果都是使用设备像素比去操作,但实际使用起来,还是会有锯齿。 这个问题苦恼了我很久,并且找了很久的相关资料,总算是功夫不负有心人,让我找到了解决方案,在github里有大神已经提供了解决方案,可以点击这里,大神在源码的基础上增加两个配置项,scaledpi,推荐使用scale参数。

    源码位置:https://github.com/eKoopmans/html2canvas/tree/develop/dist

            let imgHeight = window.document.querySelector('.content').offsetHeight // 获取DOM高度
            let imgWidth = window.document.querySelector('.content').offsetWidth // 获取DOM宽度
            let scale = window.devicePixelRatio // 获取设备像素比
            html2canvas(window.document.querySelector('.content'), {
                useCORS: true,
                scale: scale,
                 imgWidth,
                height: imgHeight
            }).then((canvas) => {
              window.document.querySelector('.content').remove()
              let elemImg = `<img src='${canvas.toDataURL('image/png')}' id='canvas-img' style='height: ${imgHeight}px;border-radius: 10px;${imgWidth}px'/>`
              window.document.querySelector('.container').innerHTML = elemImg
            })
    

    最终生成出来的图片,是清晰并且最接近DOM的图片

    3.生成的图片中若包含二维码,微信长按图片偶现无法识别?

    这个问题主要出现在使用单页面框架(如VUE)的页面. 感谢 sundaypig提出的解决方案。 很简单,就是不使用路由切换,使用window.location.href直接跳转刷新页面
        location.href="www.abc.com/share/xxx"
    

    PS:这个问题可以解决所有页面中偶现二维码无法识别的情况

    4.生成的图片中文字间距较大?

    这个暂时无法完美解决,可以尝试用css属性:letter-spacing来设置字间距

  • 相关阅读:
    JUnit之持续集成(CI,Continuous Integration)
    Junit初级编码(二)探索JUnit核心
    《opencv学习》 之 特征检测与匹配
    opencv小问题大智慧
    opencv3.1+contrib的配置大总结(配置了两天,遇到问题无数)
    《图像处理实例》 之 透视变换
    《图像处理实例》 之 物体计数
    《图像处理实例》 之 操作规则的圆
    《电路学习第三天》 之 彩扩机项目设计
    《图像处理实例》 之 提取特殊背景的直线
  • 原文地址:https://www.cnblogs.com/zhangycun/p/9247707.html
Copyright © 2011-2022 走看看