为什么 canvas.toBlob 和 canvas.toDataURL 有不同的 return 类型
Why do canvas.toBlob and canvas.toDataURL have different return types
canvas.toBlob() 需要回调函数,但 canvas.toDataURL() returns 同步结果。为什么不同?这不是问题,但我非常好奇,我找不到解释为什么会这样。
因为 toDataURL
是早期错误...
在(由 Safari IIRC)实现时,FileAPI 仍处于讨论阶段,导出 canvas 的结果已经是一种需要。所以他们做了这个方法,把return的数据做成一个方便的数据URL,你可以直接作为文档中几个元素的src
使用。此时,return 同步听起来是个好主意,Canvas API 中的所有内容都是同步的。
但是几年后,随着越来越多的实现,越来越多的使用,以及新的 APIs,toDataURL
显然不是一个好主意。就像同步 XHR 一样,如果你足够大,可以记住。
即使您可以同步方式获取数据 URL,显示它也将是一个异步任务。
从 canvas 生成图像文件是一个缓慢的操作,您需要导出所有像素数据,取消相乘,然后调用压缩算法。
除此之外,数据 URL 需要存储为 base64 编码的字符串,比它表示的二进制数据大 34%,并且每次在 DOM...
文件API 介绍了在内存中保存二进制数据并能够显示、操作或将其原样发送到服务器的方法。所有这些都意味着最小的内存开销 => 数据 URLs 已过时(对于大多数情况)。
因此决定添加一个新方法,该方法将利用这些新的 APIs,并且 return 一个 Blob 而不是一个数据 URL。在与 UI 阻塞操作的共同斗争中,已决定此方法将是异步的 (但不幸的是,那是在 Promise 出现之前...)。现在所有需要同步完成的就是获取像素数据,就像 getImageData
那样。其余操作可以并行完成。
canvas.toBlob() 需要回调函数,但 canvas.toDataURL() returns 同步结果。为什么不同?这不是问题,但我非常好奇,我找不到解释为什么会这样。
因为 toDataURL
是早期错误...
在(由 Safari IIRC)实现时,FileAPI 仍处于讨论阶段,导出 canvas 的结果已经是一种需要。所以他们做了这个方法,把return的数据做成一个方便的数据URL,你可以直接作为文档中几个元素的src
使用。此时,return 同步听起来是个好主意,Canvas API 中的所有内容都是同步的。
但是几年后,随着越来越多的实现,越来越多的使用,以及新的 APIs,toDataURL
显然不是一个好主意。就像同步 XHR 一样,如果你足够大,可以记住。
即使您可以同步方式获取数据 URL,显示它也将是一个异步任务。
从 canvas 生成图像文件是一个缓慢的操作,您需要导出所有像素数据,取消相乘,然后调用压缩算法。
除此之外,数据 URL 需要存储为 base64 编码的字符串,比它表示的二进制数据大 34%,并且每次在 DOM...
文件API 介绍了在内存中保存二进制数据并能够显示、操作或将其原样发送到服务器的方法。所有这些都意味着最小的内存开销 => 数据 URLs 已过时(对于大多数情况)。
因此决定添加一个新方法,该方法将利用这些新的 APIs,并且 return 一个 Blob 而不是一个数据 URL。在与 UI 阻塞操作的共同斗争中,已决定此方法将是异步的 (但不幸的是,那是在 Promise 出现之前...)。现在所有需要同步完成的就是获取像素数据,就像 getImageData
那样。其余操作可以并行完成。