DOM导出为图片

Yukino 1,068 2022-04-08
背景:前段时间接到一个需求,有一个用户自定义上传的图片会频繁更改,但大多都是更改文本内容,
所以提出了制作几套模板针对不同的场景,用户可以输入、更改文本内容,然后生成图片保存。

实现方式

在网上搜索到《基于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,最后导出。

注意点:

  1. 跨域,如果导出的dom中包含图片,且图片与网站不是同源的(比如图片有CDN代理),则需要在option中添加useCORS,并在img标签上添加crossorigin='anonymous'属性;
  2. 图片透明度,如果导出时需要保留透明度,就需要将导出格式更改为image/png,jpeg是不会存储透明度的,但是大小会相比png小很多,如果对透明度没有要求的建议导出为jpeg节省存储空间;
  3. 图片分辨率,上面的代码可以看的到,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