我正在使用 puppeteer 开发图像比较 Web 应用程序,这就是我想要做的事情:
- 打开 puppeteer 页面,转到带有模型查看器(谷歌的网络图形 API)网络组件的渲染页面。
- 用模型查看器渲染一些东西
- 渲染完成后截取rgba屏幕截图(使用 page.screenshot())
- 关闭页面。
- 将截图作为图像比较api的参数(输入应该是nodejs Buffer类型或png文件)
除了第 3 步之外,一切都运行良好,因为通过使用 page.screenshot() 方法,输出 png 文件是RGB格式,而不是RGBA。我没有找到办法做到这一点,这是我尝试过的两种解决方案:
解决方案 1:模型查看器 api 有一个名为 toBlob() 的内置函数,它返回我需要的模型查看器组件的所有 RGBA 数据的 Blob 对象。我知道如何将 Blob 对象转换为 Buffer,所以如果我得到 Blob 对象,这应该可以工作。这是我尝试获取 blob 对象的方法。
const Blob = await page.evaluate(async () => {
const modelViewer = document.querySelector('#modelViewer');
const Blob = await (modelViewer as any).toBlob();
//console.log(Blob) this shows a correct Blob object under puppteer browser's devtool
// in order to return something, i have convert Blob object all the way to a unit8Array
//const arrayBuffer = await new Response(Blob).arrayBuffer();
//const unit8Array = new Uint8Array(arrayBuffer);
return Blob;
});
问题是 page.evaluate() 返回的 Blob 对象是空的。我在 evaluate() 函数中检查了 Blob 对象,它已正确记录在 puppteer 浏览器的 devtool 上。我认为原因是 evaluate() 要求返回值是可序列化的,而 Blob 对象可能不是。为了将不为空的内容返回到应用程序的上下文中,我必须将其一直转换为 unit8Array。但是我还没有找到将 unit8Array 转换为 Buffer 对象的方法,即使有,我认为这可能非常低效,因为包含所有像素信息的 Blob 对象可能非常大,并且可能会有很多计算在转换过程中。
解决方案 2:我正在考虑使用 page.evaluateHandle() 来获取模型查看器组件的 jsHandle 并在我的应用程序的上下文中运行 goBlob,如果我错了,请纠正我,但我认为 jsHandle 只应该在 puppteer 的上下文中使用,对? 所以这个解决方案应该是错误的
因此,我的任何解决方案都可以改进吗?还是有更好的解决方案?谢谢 !