使用 MediaProjection 捕获屏幕内容时隐藏窗口

问题描述 投票:0回答:1

我正在使用 MediaProjection API 来捕获屏幕内容。但是,我的应用程序还使用非应用程序窗口(如直接添加到

WindowManager
的系统警报对话框)作为覆盖,这是我想从捕获的屏幕内容中省略的东西(好像它是不可见的)。

当我将窗口设置为安全时,这会导致一个黑色矩形代替窗口。

有什么方法可以捕获屏幕内容,就好像覆盖窗口根本不存在一样?

编辑:要清楚,我希望覆盖窗口对用户可见但不被捕获。

android android-windowmanager
1个回答
1
投票

注意:此方法要求您感兴趣的小部件在屏幕上显示时隐藏/忽略应该是 50% 透明(不能太不透明或太透明)并且您需要知道小部件的形状作为掩码以便将其完全隐藏在输出帧上透明。这最初不是我的主意,我想在我现在不记得的类似帖子中表扬他/她。 因为你有 50% 的透明度,所以你有 0.5 的 alpha,这就是你如何将小部件像素与实际背景合成以产生新的屏幕像素。

resultantPixel(R channel) = widget(R) * 0.5 + background(R) * 0.5,

resultantPixel(G channel) = widget(G) * 0.5 + background(G) * 0.5,

resultantPixel(B channel) = widget(B) * 0.5 + background(B) * 0.5

现在,当您完成像素记录后,您可以在每个通道上进行反向阿尔法合成,因为您已经知道小部件的像素值。您可以提取原始背景像素值

originalPixel(channel X) = (captuedInputImage(X) - (widget(X) / 2)) * 2

但是您只需要在小部件和背景截取的像素上应用这种反向合成,因此您需要知道小部件的形状作为掩码,其中小部件以

#ffffff
呈现,背景以
#000000
呈现。然后你最终可以将像素混合为,

resultFrame = inputCapturedImage | (maskImage & reverseCompositedImage)

就是这样!现在 resultFrame 现在显示没有小部件的显示,就好像它完全不可见一样。

那为什么要选择50%的透明度呢?

因为它是获得准确结果的最优值。如果您将小部件的透明度降低 20%,则很难重新创建原始背景值。想象一下,在 50% 透明的情况下,您的原始背景通道值为

41
,并且在使用小部件渲染时它将表示为
20
整数,因为
(41 * 0.5 ->alpha)
并且当应用反向合成时,我们再次将其与相同的 alpha 因子
20 * 2 = 40
相乘。所以你可以看到我们只有
1
像素值不准确,这是可以忽略的,但是如果你选择
0.1
的 alpha,你将有更高的像素值不准确。如果您进行数学计算并使小部件对实际用户不那么可见,那么将透明度提高到 50% 以上将对准确性产生较小影响,因此
50%
是最佳值。

© www.soinside.com 2019 - 2024. All rights reserved.