后台设置
我有一个 Web 应用程序,它处理从一组其他图像创建图像。我选择这样做的方法是读取一组图像并将它们放置在 HTML 画布上。然后,我将每个画布作为 jpeg 导出到第三方 API,并使用toDataURL
并将其转换为 Blob。我面临的问题是我有许多这样的画布都将数据导出为 jpg 并且它消耗了大量资源。当每个画布尝试调用toDataURL
.
问题
我发现调用画布的toDataUrl()
ortoBlob()
可能会非常慢,尤其是对于大画布尺寸。我想利用网络工作者的多线程特性。
首先,我尝试传入画布对象,但抛出了一个错误。事实证明,对象是一个问题,而且似乎它们要么被转换为字符串,要么在无法克隆时失败。无论哪种方式,我发现传递上下文的图像数据确实有效。数据以原始 RGB 值的形式作为Uint8ClampedArray
画布上下文的方法传递getImageData()
。
主.js
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var worker = new Worker('myWorker.js');
worker.postMessage({
image: context.getImageData(0, 0, canvas.width, canvas.height)
});
myWorker.js
this.onmessage = function(e) {
// GOAL: turn e.data.image into an image blob or dataUrl and return it.
// e.g. this.postMessage(new Blob([e.data.image.data], {type: 'image/jpg'});
}
我认为归结为知道如何将Uint8ClampedArray
保存 RGB 信息的 a 转换为 jpg/png 数据。
我认为这可能有用的原因是我相信getImageData
只是从画布上下文中复制现有数据结构,因此不像toDataUrl
. 我在调用类似于以下代码块的内容时捕获了 cpu 配置文件:
var image = context.getImageData(0, 0, canvas.width, canvas.height)
var dataUrl = canvas.toDataURL('image/jpeg');
并得到:
所以,考虑到这一点,我想把这个过程的重担转移到一个网络工作者身上。我什至不介意网络工作者内部是否需要更长的时间,只要它发生在另一个进程中。
关于它的一些额外想法:
- 添加一个额外的库来进行转换是可以的,但是提供如何将外部库添加为 web worker 文件的依赖项的奖励积分。现在我正在为应用程序使用 browserify。也许为网络工作者创建另一个浏览器化包?
- 我最终需要一个 jpeg(对于第三方 API),因此将其转换为 png 只是作为转换为 jpeg 的一个步骤。
- 我尝试降低 中
encoderOptions
的第二个选项toDataURL
,作为加快进程的一种方式,但我没有看到太大的变化