Предварительный просмотр камеры Android в двух видах (предварительный просмотр камеры с несколькими объективами)
Мне нужно два превью камеры в моем приложении. Тем не менее, Android-камера может дать только один предварительный просмотр за раз. Есть ли способ передать / скопировать этот предварительный просмотр в другое представление? Я сталкивался с этим вопросом, как создать несколько линз или превью, используя одну камеру в 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) {
}
}
Выход:
1 ответ
Начните с отправки предварительного просмотра камеры в SurfaceTexture вместо Surface, связанного с View. Это берет выходные данные камеры и делает ее доступной для использования в качестве текстуры GLES.
Тогда вместо двух TextureViews
, просто визуализируйте два текстурированных квадра с помощью GLES, каждый из которых занимает половину одного представления. Это проще, чем рендеринг на две разные поверхности (нужно беспокоиться только об одном контексте EGL). Если вы раньше не работали с OpenGL ES, может возникнуть некоторая кривая обучения.
Части, которые вам нужны, можно найти в Графика. Рассмотрим, например, действия "Непрерывный захват" и "Показать + захват камеры". Оба направляют выход камеры на SurfaceTexture
и сделать это дважды. Для них это один раз на экран и один раз на вход видеокодера, но это та же идея. Если вы посмотрите на "Hardware Scale Exerciser", вы увидите, что он вспыхивает текстурированным квадом, который прыгает по экрану; Вы можете использовать это как пример того, как установить размер и положение квадратора.
Там также "Двойное декодирование", который использует пару TextureViews
показать два декодированных фильма рядом. Вы не хотите делать то, что он делает - он получает контент из двух разных источников, а не показывает один источник дважды.
Различные виды деятельности используют GLES с TextureView
, SurfaceView
, а также GLSurfaceView
, Каждый тип представления имеет уникальные преимущества и ограничения.
Обновление: новое (не ответ на этот вопрос) действие " текстура с камеры", вероятно, наиболее близко к тому, что вы хотите. Он отправляет предварительный просмотр камеры в SurfaceTexture и демонстрирует, как перемещать, изменять размер, вращать и масштабировать изображение, визуализируя его с помощью GLES.