Frage Vorschau der Android-Kamera in zwei Ansichten (Kamera-Vorschau mit mehreren Objektiven)


Ich brauche zwei Kameravorschauen in meiner App. Allerdings kann Android-Kamera nur eine Vorschau auf einmal geben. Gibt es eine Möglichkeit, diese Vorschau in eine andere Ansicht zu pipeline / kopieren? Ich bin auf diese Frage gestoßen So erstellen Sie Multi-Objektive oder Vorschau mit einer Kamera in Android und er sagt das

On Android 3.0 or later, you can use the setPreviewTexture method to pipe the preview data into an OpenGL texture, which you can then render to multiple quads in a GLSurfaceView or equivalent.

Aber ich habe keine Ahnung, wie man das an mehrere Quads rendern soll GLSurfaceView.Ich muss Android 4.0 + unterstützen. Aber ich möchte kein Vorschaubild aus dem Vorschau-Callback verwenden. Es verursacht erhebliche Verzögerung. Jede Hilfe wäre willkommen. Vielen Dank!!

Hier ist mein Code für die Einzelvorschau

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    tools:context=".MainActivity" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:weightSum="10" >

        <TextureView
            android:id="@+id/textureView1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="5" />

        <TextureView
            android:id="@+id/textureView2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="5" />
    </LinearLayout>

</RelativeLayout>

Hauptaktivität.java

public class MainActivity extends Activity implements SurfaceTextureListener{

    private Camera mCamera;
    private TextureView mTextureView1;
    private TextureView mTextureView2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextureView1 = (TextureView) findViewById(R.id.textureView1);
        mTextureView2 = (TextureView) findViewById(R.id.textureView2);

        mTextureView1.setSurfaceTextureListener(this);
    }



    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
            int height) {


        try {
            mCamera = Camera.open(getCameraId());
            mCamera.setPreviewTexture(surface);
            CameraInfo cameraInfo = new CameraInfo();
            Camera.getCameraInfo(getCameraId(), cameraInfo);
            setCameraDisplayOrientation(this, getCameraId(), mCamera);
            mCamera.startPreview();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        try {
            mCamera.stopPreview();
            mCamera.release();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
            int height) {


    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }


}

Ausgabe: enter image description here


5
2018-03-20 10:25


Ursprung


Antworten:


Beginnen Sie mit dem Senden der Kameravorschau an a Oberflächentextur anstelle einer Oberfläche, die einer Ansicht zugeordnet ist. Das nimmt die Ausgabe der Kamera und stellt sie als GLES-Textur zur Verfügung.

Dann statt zwei TextureViewsRendern Sie einfach zwei texturierte Quads mit GLES, die jeweils die Hälfte einer einzigen Ansicht einnehmen. Dies ist einfacher als das Rendern auf zwei verschiedene Oberflächen (nur ein EGL-Kontext, um den Sie sich sorgen müssen). Wenn Sie noch nicht mit OpenGL ES gearbeitet haben, können Sie etwas lernen.

Die benötigten Teile finden Sie in Grafika. Betrachten Sie beispielsweise die Aktivitäten "Kontinuierliche Aufnahme" und "Zeigen + Kamera aufnehmen". Beide richten die Kameraausgabe auf a aus SurfaceTexture und render es zweimal. Für diese ist es einmal auf dem Bildschirm und einmal auf den Eingang eines Video-Encoders, aber es ist die gleiche Idee. Wenn Sie sich "Hardware Scaler Exerciser" ansehen, können Sie sehen, wie es einen texturierten Quad schlägt, der um den Bildschirm herumspringt. Sie können dies als Beispiel für die Einstellung der Größe und Position des Quads verwenden.

Es gibt auch "Double decode", das ein Paar verwendet TextureViews um zwei decodierte Filme nebeneinander zu zeigen. Sie möchten nicht das tun, was sie tut - sie empfängt Inhalte aus zwei verschiedenen Quellen und zeigt nicht zweimal eine einzige Quelle an.

Die verschiedenen Aktivitäten nutzen GLES mit TextureView, SurfaceView, und GLSurfaceView. Jeder Ansichtstyp bietet einzigartige Vorteile und Einschränkungen.

Aktualisieren: Die neue (äh als diese Antwort) "Textur von der Kamera"Aktivität ist wahrscheinlich am ehesten mit dem, was Sie wollen. Es sendet die Kamera Vorschau an eine SurfaceTexture und zeigt, wie Sie das Bild verschieben, Größe ändern, drehen und zoomen, indem Sie es mit GLES rendern.


10
2018-03-20 19:37