在前端开发中,我们经常会用到 Canvas 来绘制各种图形,但是有时候我们需要将 Canvas 中的图形导出为图片,以便于分享、打印等用途。本文将介绍如何实现 Canvas 图片导出,并解决在此过程中可能遇到的问题。
常规方法:toDataURL
Canvas 对象提供了 toDataURL 方法,可以将 Canvas 导出为一张 base64 格式的图片。使用方法如下:
----- ------ - --------------------------------- ----- --- - ------------------------ -- ------- ----- ------- - ------------------- -- -- ------ ------
这个方法看起来非常简单,但是它存在以下问题:
- 性能问题:toDataURL 生成的是一个非常大的字符串,如果 Canvas 非常大,就会造成浏览器崩溃或者卡顿。
- 跨域问题:如果 Canvas 中包含跨域图片,toDataURL 会抛出安全错误。
- 质量问题:默认情况下,toDataURL 导出的图片质量比较差,因为它使用的是 image/png 格式,而不是更好的 image/jpeg 或者 image/webp 格式。
为了解决这些问题,我们需要使用其他的方法。
使用 OffscreenCanvas
OffscreenCanvas 是 Web Worker 中的一个概念,它可以在后台线程中进行绘制操作,从而减轻主线程压力。但是 OffscreenCanvas 也可以在主线程中使用,并且它提供了 toBlob 方法,可以将 Canvas 导出为 Blob 对象,这样就不会产生过大的字符串了。
----- --------------- - --- ---------------------- -------- ----- --- - --------------------------------- -- ------- ----------------------------- -- - -- -- ---- ------------------- -- ------------- ---------
注意,虽然 OffscreenCanvas 的设计初衷是用于 web worker 中,但是并不是所有浏览器都支持 OffscreenCanvas,所以在使用之前需要进行兼容性检查。
解决跨域问题
如果 Canvas 中包含跨域图片,即使使用 OffscreenCanvas,导出图片时仍然会抛出安全错误。这时候我们需要通过设置 CORS 来解决这个问题。
CORS(Cross-Origin Resource Sharing)是一种机制,允许网页向其他域名的服务器请求数据,从而避免了浏览器的同源策略限制。只需要在服务器端设置 Access-Control-Allow-Origin 头部,就可以开启 CORS 机制。
如果你没有掌握 CORS 的相关知识,建议先学习一下。
解决质量问题
我们可以使用 canvas.toBlob 方法的第三个参数,来指定输出图片的质量。这个参数是一个 0~1 的浮点数,表示图片的质量,值越大,图片质量越好,文件大小也越大。
----- --------------- - --- ---------------------- -------- ----- --- - --------------------------------- -- ------- ----------------------------- -- - -- -- ---- ------------------- -- ------------- ---------
示例代码
下面是一个完整的 Canvas 导出为 Blob 对象的例子:
-------- -------------------------- ------- - --- - ----- - ---- - ------------ ------- - - - - -------- -- --------- ---------- ------------------- - ----- --- ------------- ----- ------ ----- - ------ --- ----------------- -- - ----- - ----------------------------------------------------------- -------- ---------------------------------------------------------------------------------------