我正在尝试根据自己的活动创建4个摄像机预览流。我创建了一个TextureView,将其注册到feed的camera2 API,然后在SurfaceView上设置了一个侦听器,以侦听feed的更改并相应地更新其他3个预览(ImageViews)。您可以在下面的代码中看到:
private final TextureView.SurfaceTextureListener mSurfaceTextureListener
= new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
cameraHandler.openCamera(width, height);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
for (ImageView mSecondaryPreview : mSecondaryPreviews) {
Bitmap frame = Bitmap.createBitmap(mTextureView.getWidth(), mTextureView.getHeight(), Bitmap.Config.ARGB_8888);
mTextureView.getBitmap(frame);
mSecondaryPreview.setImageBitmap(frame);
}
}
};
如您所见,必须从TextureView中读取每一帧,提取位图,然后设置其他3个ImageView流的位图。我最初尝试在速度很慢的UI线程上执行此操作,然后尝试将其提交给具有更好帧速率的后台处理程序,但由于负载导致应用崩溃导致很多问题。
谢谢
因此,如果可以像在GLSurfaceView
中那样使this question与照相机预览一起使用,则只需再添加6个多边形,就可以再制作3个副本。让我解释一下它们的布局。 vtmp
和ttmp
分别以GL_TRIANGLE_STRIP
形式描述两个三角形的矢量坐标和纹理坐标:
float[] vtmp = {
1.0f, 1.0f, //Top right of screen
1.0f, -1.0f, //Bottom right of screen
-1.0f, 1.0f, //Top left of screen
-1.0f, -1.0f //Bottom left of screen
};
float[] ttmp = {
1.0f, 1.0f, //Top right of camera surface
0.0f, 1.0f, //Top left of camera surface
1.0f, 0.0f, //Bottom right of camera surface
0.0f, 0.0f //Bottom left of camera surface
};
步骤1:让我们将原始类型更改为GL_TRIANGLES
,因为使用GL_TRIANGLE_STRIP
会很困难:
float[] vtmp = {
//Triangle 1:
1.0f, 1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
//Triangle 2:
-1.0f, 1.0f,
1.0f, -1.0f,
-1.0f, -1.0f
};
//I've attempted to fix the left-right inversion here by altering the
//texture X (u) coordinates. Hope I did it right!
float[] ttmp = {
//Triangle 1:
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
//Triangle 2:
0.0f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f
};
pVertex = ByteBuffer.allocateDirect(12*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
(...)
pTexCoord = ByteBuffer.allocateDirect(12*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
(...)
GLES20.glVertexAttribPointer(ph, 2, GLES20.GL_FLOAT, false, 6*2, pVertex);
GLES20.glVertexAttribPointer(tch, 2, GLES20.GL_FLOAT, false, 6*2, pTexCoord );
(...)
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6); //Careful: Multiple changes on this line
(...)
如果第1步顺利进行,那么在第2步中添加额外的三角形:
float[] vtmp = {
//Triangle 1:
0.0f, 1.0f,
0.0f, 0.0f,
-1.0f, 1.0f,
//Triangle 2:
-1.0f, 1.0f,
0.0f, 0.0f,
-1.0f, 0.0f,
//Triangle 3:
1.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
//Triangle 4:
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 0.0f,
//Triangle 5:
1.0f, 0.0f,
1.0f, -1.0f,
0.0f, 0.0f,
//Triangle 6:
0.0f, 0.0f,
1.0f, -1.0f,
0.0f, -1.0f,
//Triangle 7:
0.0f, 0.0f,
0.0f, -1.0f,
-1.0f, 0.0f,
//Triangle 8:
-1.0f, 0.0f,
0.0f, -1.0f,
-1.0f, -1.0f
};
float[] ttmp = {
//Triangle 1:
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
//Triangle 2:
0.0f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f,
//Triangle 3:
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
//Triangle 4:
0.0f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f,
//Triangle 5:
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
//Triangle 6:
0.0f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f,
//Triangle 7:
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
//Triangle 8:
0.0f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f
};
pVertex = ByteBuffer.allocateDirect(48*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
(...)
pTexCoord = ByteBuffer.allocateDirect(48*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
(...)
GLES20.glVertexAttribPointer(ph, 2, GLES20.GL_FLOAT, false, 24*2, pVertex);
GLES20.glVertexAttribPointer(tch, 2, GLES20.GL_FLOAT, false, 24*2, pTexCoord );
(...)
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 24);
(...)
我是在没有测试的情况下手工完成的,因此如果出现严重错误,您会原谅我。