Android 多个表面视图 - 裁剪问题

Android multiple surface views - clipping issue

我目前在使用多个表面视图和剪裁其中一个视图以使其显示为圆形时遇到问题。最好用图片描述:

所以在这个视图中,我有 2 个表面视图,全屏视图显示相机的预览,然后顶部显示使用 MediaPlayer 播放文件。我已经通过以下行将最上面的一个置于预览之上:

surfaceView.setZOrderMediaOverlay(true);

现在如您所见,我已尝试使用以下代码将其屏蔽为一个圆圈:

@Override
protected void dispatchDraw(Canvas canvas) {

    Path clipPath = new Path();
    clipPath.addCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2, Path.Direction.CCW);

    canvas.clipPath(clipPath);
    super.dispatchDraw(canvas);
}

但似乎还没有完全解决。我最初认为这是我的屏蔽代码的问题,但事实证明,如果我删除预览表面视图,如下图所示,屏蔽工作正常

任何人都知道为什么会发生这种情况或如何解决它:S?

感谢您的帮助

请记住,SurfaceView 有两个部分,Surface 和 View,并且 Android 图形系统使用多层。

您的所有视图都位于一个层上,通常简称为 "the View UI layer"。视图可以放置在彼此之上或之下,因为它们都被渲染到相同的像素缓冲区中。

表面出现在它们自己的图层上。默认情况下,SurfaceView 的 Surface 位于 View UI 层下方(后面)。 SurfaceView的View部分只是View系统用于布局的透明矩形。如果您在该视图上绘制(通过子类化 SurfaceView 并重写绘制方法),您将渲染与表面重叠的像素,使它们不透明。这是屏蔽表面的简单方法。

您的迷你播放器 Surface 使用 setZOrderOnTop(),它将 SurfaceView 的 Surface 的图层设置在视图 UI 的顶部(前面)。如果您的 Surface 是部分透明的,这会很方便,因为它可以让您看到它背后的视图。但是,您在 SurfaceView 的 View 上绘制的任何内容也会出现在它的后面,因此它将不再用作遮罩。

您尝试做的事情的问题在于您希望通过角落处的上表面可以看到下表面。您不能简单地用另一层屏蔽掉这些像素——您需要使它们在视频播放层本身上透明。这有点棘手,因为您需要将视频输入 GLES 纹理,然后进行渲染。

另见 graphics architecture doc