【问题标题】:Android Camera preview on two views ( Multi-lenses camera preview )两个视图上的 Android 相机预览(多镜头相机预览)
【发布时间】:2014-03-20 10:25:56
【问题描述】:

我的应用中需要两个相机预览。但是,android 相机一次只能提供一个预览。有没有办法将该预览流水线/复制到另一个视图?我遇到了这个问题How to create multi lenses or preview using one camera in Android 他这么说

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.

但我不知道如何在GLSurfaceView 中将其渲染到多个四边形。我需要支持 android 4.0+。但我不想使用预览回调中的预览帧。它会导致严重的延迟。任何帮助,将不胜感激。谢谢!!

这是我的单次预览代码

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>

MainActivity.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) {

    }


}

输出:

【问题讨论】:

  • 要明确一点:您是希望在两个相邻窗口中显示来自一个单个相机的预览帧,还是来自两个不同相机的预览帧 并排显示?
  • @fadden 我需要从两个相邻窗口中显示的单个摄像头进行预览。
  • @fadden 但正如我所说,我不想使用onPreviewFrame 来获取单个帧,因为它会引入一些延迟。
  • @AbhishekV 你完成了这个任务你能不能分享一下你是怎么做的我也卡在同一点你能帮我吗
  • @ErumHannan 我无法解决这个问题。这只是我们项目中的一个小模块,因为我忙于其他项目,所以我不能花太多时间在上面。我最终使用了 onPreviewFrame() 方法中的预览帧。也没有那么糟糕,如果您可以根据自己的需要正确设置相机预览大小,绝对不会有任何延迟。

标签: android android-camera


【解决方案1】:

首先将相机预览发送到SurfaceTexture,而不是与视图关联的 Surface。这会获取相机的输出并使其可用作 GLES 纹理。

然后,不用两个TextureViews,只需用 GLES 渲染两个带纹理的四边形,每个四边形占据单个 View 的一半。这比渲染到两个不同的表面(只需要担心一个 EGL 上下文)更容易。如果您之前没有使用过 OpenGL ES,可能会有一些学习曲线。

您需要的作品可以在Grafika找到。例如,考虑“连续捕获”和“显示 + 捕获相机”活动。两者都将相机输出定向到SurfaceTexture 并渲染两次。对于这些,它一次到屏幕,一次到视频编码器的输入,但这是相同的想法。如果您查看“Hardware scaler exerciser”,您会看到它在屏幕上反弹一个纹理四边形;您可以以此为例说明如何设置四边形的大小和位置。

还有“双重解码”,它使用一对TextureViews 并排显示两个解码的电影。你不想做它所做的事情——它从两个不同的来源接收内容,而不是两次显示一个来源。

各种活动将 GLES 与 TextureViewSurfaceViewGLSurfaceView 结合使用。每种视图类型都有独特的优势和局限性。

更新:新的(比这个答案更)“texture from camera”活动可能最接近你想要的。它将相机预览发送到 SurfaceTexture 并演示如何通过 GLES 渲染图像来移动、调整大小、旋转和缩放图像。

【讨论】:

  • 谢谢。我将处理您提供的示例并让您知道。
  • @AbhishekV 你能告诉我这个解决方案对你有用吗?你能帮我吗?我可能需要将 cameraInstance.startPreview() 发送到 SurfaceTexture 吗??
  • @user3233280 我没有进一步解决这个问题。看看 Grafika 项目。我相信你会在那里找到一些有用的代码。
  • 更新了答案——几个月后我添加了一个“来自相机的纹理”活动,它使用 GLES 呈现相机预览。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-08
  • 1970-01-01
  • 2012-03-20
  • 1970-01-01
相关资源
最近更新 更多