0

現在、複数のサーフェス ビューと、単一のビューの 1 つをクリッピングして円として表示することに問題があります。それは画像で最もよく説明されています:

したがって、このビューでは、カメラのプレビューを表示しているフルスクリーンビューと、MediaPlayer でファイルを再生しているトップビューの 2 つのサーフェスビューがあります。次の行を使用して、一番上のものをプレビューの上に配置しました。

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?

ご協力いただきありがとうございます

4

1 に答える 1

3

SurfaceView には Surface と View の 2 つの部分があり、Android グラフィック システムは複数のレイヤーを使用することに注意してください。

すべてのビューは、通常は単に「ビュー UI レイヤー」と呼ばれる単一のレイヤー上にあります。ビューはすべて同じピクセル バッファーにレンダリングされるため、ビューを上下に配置できます。

サーフェスは独自のレイヤーに表示されます。デフォルトでは、SurfaceView の Surface は View UI レイヤーの下 (後ろ) にあります。SurfaceView のビュー パーツは、ビュー システムがレイア​​ウトに使用する単なる透明な四角形です。(SurfaceView をサブクラス化し、draw メソッドをオーバーライドすることによって) その View に描画すると、Surface に重なるピクセルがレンダリングされ、不透明になります。これは、サーフェスをマスクする簡単な方法です。

ミニプレーヤー Surface は を使用しますsetZOrderOnTop()。これにより、その SurfaceView の Surface のレイヤーが View UI の上 (前) になるように設定されます。これは、サーフェスの背後にあるビューを表示できるため、サーフェスが部分的に透明な場合に便利です。ただし、SurfaceView のビューに描画したものはすべてその背後にも表示されるため、マスクとして機能しなくなります。

あなたがやろうとしていることの問題は、コーナーの上部サーフェスを通して下部サーフェスを見えるようにしたいということです。これらのピクセルを別のレイヤーで単純にマスクすることはできません。ビデオ再生レイヤー自体でそれらを透明にする必要があります。ビデオを GLES テクスチャにフィードしてからレンダリングする必要があるため、これは少し注意が必要です。

グラフィックス アーキテクチャのドキュメントも参照してください。

于 2016-02-26T02:35:33.457 に答える