如何使用木偶戏拍摄RGBA屏幕截图?

时间:2020-07-16 03:01:08

标签: javascript typescript puppeteer rgba model-view

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

  1. 打开一个伪造者页面,转到带有模型查看器(谷歌的网络图形API)网络组件的渲染页面。
  2. 使用模型查看器渲染一些东西
  3. 渲染完成后,
  4. 拍摄一个 rgba 屏幕截图(使用page.screenshot())
  5. 关闭页面。
  6. 将屏幕截图用作图像比较api的参数(输入应为nodejs Buffer类型或png文件)

除第3步外,其他所有操作均正常,因为使用page.screenshot()方法,输出的png文件为 RGB 格式,而不是 RGBA 。我没有找到解决方法,这是我尝试过的两个解决方案:

解决方案1 ​​:model-viewer api具有一个名为toBlob()的内置函数,该函数返回我需要的model-viewer组件的所有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对象为空。我在validate()函数中将选中的Blob对象加倍,并将其正确记录在puppteer浏览器的devtool上。我认为原因是评价()要求返回值可序列化,而Blob对象则可能不需要。为了向应用程序的上下文返回不为空的内容,我必须将其一直转换为unit8Array。但是我还没有找到一种将unit8Array转换为Buffer对象的方法,即使有一个,我也认为效率很低,因为包含所有像素信息的Blob对象可能真的很大,并且可能会有很多计算在转换过程中。

解决方案2 :我正在考虑使用page.evaluateHandle()获取模型查看器组件的jsHandle并在应用程序的上下文中运行goBlob,如果我错了,请更正我,但我认为jsHandle只能在普普特的背景下使用,对吗?所以这个解决方案应该是错误的

因此,我的解决方案有待改进吗?还是有更好的解决方案?谢谢!

1 个答案:

答案 0 :(得分: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 < sub> B ,B B )=(ar,ag,ab)。然后,您可以使用

找到原始的字母值

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值的精度,但这对于实际的单元测试而言可能无关紧要。