将页面内容保存为图片,一般采用html2canvas的方式,但是该方式存在一个问题,如果处理不好则生成的图片会模糊不清晰,从jquery时就用过这个插件,但是在Vue系列框架中还是第一次用,中途也遇到过很多问题,特此记录。
由于是H5项目,并且要求使用uniapp,但是该方法在Vue等框架中也适用
<view class="on-court-poster" id="onCourtPoster">
<!-- 页面布局仅供参考 -->
<view>页面需要生成图片的内容</view>
<!-- 用来保存生成图片 -->
<image :src="prurl" alt="分享海报" id="posterIimg" class="poster-img" v-show="!hidden"/>
</view>
html2canvas插件配置
import html2canvas from "html2canvas"
// 校正截图不全问题
window.pageYoffset = 0;
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
const domObj = document.getElementById('需要生成图片的内容外层的盒子id')
let width = domObj.offsetWidth; //获取dom 宽度
let height = domObj.offsetHeight; //获取dom 高度
let canvas = document.createElement("canvas"); //创建一个canvas节点
const scale = 2; //定义任意放大倍数 支持小数
canvas.width = width * scale; //定义canvas 宽度 * 缩放
canvas.height = height * scale; //定义canvas高度 *缩放
let context = canvas.getContext('2d');
// 【重要】关闭抗锯齿
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
console.log('父元素宽度', width)
console.log('父元素高度',height)
let opts = {
// 注意: allowTaint: true 和 useCORS: true 不能同时设置,两者只有一个起作用
scale: scale, // 添加的scale 参数
canvas: canvas, //自定义 canvas
// allowTaint: true, // 允许污染,允许画布上有跨域图片 不建议使用 后面详细补充
logging: true, //日志开关,便于查看html2canvas的内部执行流程
width: width, //dom 原始宽度
height: height,
dpi:300,
useCORS: true ,// 【重要】开启跨域配置
letterRendering: true,
};
html2canvas(domObj, opts).then(canvas => {
// 在微信里,可长按保存或转发
_this.prurl = canvas.toDataURL('image/png');
let detail = document.getElementById('posterIimg') // 防止图片url的标签的id
detail.style.width = canvas.width / 2 + "px";
detail.style.height = canvas.height / 2 + "px";
_this.hidden = false;
})
以上方法为最终成功的配置,之前采用过动态生成img标签的方式,但是会出现图片模糊的情况,同时在微信浏览时有的手机机型还会识别不出生成的图片,具体原因还未可知
注意点
-
allowTaint: true
和useCORS: true
都是解决跨域问题的方式,不同的是使用allowTaint
会对canvas造成污染,导致无法使用canvas.toDataURL
方法,所以这里不能使用allowTaint: true
- 在跨域的图片里设置
crossOrigin="anonymous"
并且需要给imageUrl
加上随机数 -
canvas.toDataURL('image/jpg')
是将canvas转成base64图片格式。
1 生成图片裁剪不完整
解决:将图片 html 放在页面根部,即相当直接放在 body 的内部
2 需要绘制的图片跨域问题
解决: 1) 设置 useCORS: true, 使用跨域(当allowTaint为true时这段代码没什么用,下面解释)
2) img图片设置属性 crossorigin="anonymous"
3 转换base64不成功
解决:allowTaint: true 允许污染,被污染的 canvas 是没法使用 toDataURL() 转 base64 流的
4 图片清晰度差
解决:html结构样式放大一倍来设置,最后缩小一倍显示在页面中