背景:前段时间接到一个需求,有一个用户自定义上传的图片会频繁更改,但大多都是更改文本内容,
所以提出了制作几套模板针对不同的场景,用户可以输入、更改文本内容,然后生成图片保存。
实现方式
在网上搜索到《基于html2canvas实现网页保存为图片及图片清晰度优化》这篇文章,写的很详细,就参考实现了出来。
整体思路是用HTML实现对应的模板样式,然后用html2canvas这个开源库将Dom转化成canvas,最后用canvas的toDataURL()方法将canvas导出为图片。
直接上代码:
import html2canvas from 'html2canvas';
export default async function html2image(outputWidth = 1920, targetElementId = 'dom2image') {
const targetElement = document.querySelector(`#${targetElementId}`);
const targetWidth = targetElement.clientWidth;
const targetHeight = targetElement.clientHeight;
const scale = (outputWidth / targetWidth).toFixed(2);
const option = {
width: targetWidth,
height: targetHeight,
scale,
useCORS: true,
backgroundColor: 'rgba(0, 0, 0, 0)'
}
return new Promise((resolve, reject) => {
html2canvas(targetElement, option).then(function(canvas) {
const image = canvas.toDataURL('image/jpeg', 1);
resolve(image);
});
})
}
整体还是比较简单的,传入Dom的Id、宽高、缩放比例、背景等,通过html2canvas将Dom转换为canvas,最后导出。
注意点:
- 跨域,如果导出的dom中包含图片,且图片与网站不是同源的(比如图片有CDN代理),则需要在option中添加useCORS,并在img标签上添加
crossorigin='anonymous'
属性; - 图片透明度,如果导出时需要保留透明度,就需要将导出格式更改为
image/png
,jpeg是不会存储透明度的,但是大小会相比png小很多,如果对透明度没有要求的建议导出为jpeg节省存储空间; - 图片分辨率,上面的代码可以看的到,dom并不需要和实际导出的分辨率大小一样,可以通过设置scale来实现缩放。
参考文章:
【1】https://segmentfault.com/a/1190000011478657
【2】https://github.com/niklasvh/html2canvas
【3】https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toDataURL