2

我正在使用 puppeteer 开发图像比较 Web 应用程序,这就是我想要做的事情:

  1. 打开 puppeteer 页面,转到带有模型查看器(谷歌的网络图形 API)网络组件的渲染页面。
  2. 用模型查看器渲染一些东西
  3. 渲染完成后截取rgba屏幕截图(使用 page.screenshot())
  4. 关闭页面。
  5. 将截图作为图像比较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 的上下文中使用,对? 所以这个解决方案应该是错误的

因此,我的任何解决方案都可以改进吗?还是有更好的解决方案?谢谢 !

4

1 回答 1

1

如果您想坚持使用 Puppeteer 的截图工具,您是否考虑过更改页面背景并以代数方式查找 alpha 值?将颜色 (r, g, b, a) 放在白色上给出的 RGB 值为 (R W , G W , B W ) = (ar + (1-a)255, ag + (1-a)255, ab + (1-a)255)),而将其置于黑色则得到 (R B , G B , B B ) = (ar, ag, ab)。然后,您可以找到原始的 alpha 值

R W - R B = (1 - a)255

a = 1 - (R W - R B )/255

然后简单地将 (R B , G B , B B ) 除以a以恢复组件 (r, g, b)。

您读取的 RGB 值被四舍五入为整数,这将影响您确定 alpha 值的精度,但这对于实际的单元测试可能无关紧要。

于 2020-07-21T12:41:55.550 回答