问题
I am trying to create 4 streams of my camera preview on my activity. I created a TextureView which is registered to the camera2 API for the feed and then I set up a listener on the SurfaceView in order to listen to changes for the feed and update the other 3 previews (ImageViews) accordingly. You can see in my code below:
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);
}
}
};
As you can see this has to read from the TextureView for every frame, extract the bitmap and then set the bitmap of the other 3 ImageView streams. I tried to do this on the UI thread initially which is very slow and then tried to submit it to the background handler which was better frame rate but caused a lot of issues with the app crashing due to the load.
Thanks
EDIT
So in order to crop the bottom 0.4375 of the preview, I changed ttmp to
float[] ttmp = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.4375f,
0.0f, 0.4375f,
1.0f, 1.0f,
1.0f, 0.4375f,
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.4375f,
0.0f, 0.4375f,
1.0f, 1.0f,
1.0f, 0.4375f,
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.4375f,
0.0f, 0.4375f,
1.0f, 1.0f,
1.0f, 0.4375f,
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.4375f,
0.0f, 0.4375f,
1.0f, 1.0f,
1.0f, 0.4375f
};
but this did not crop as expected
回答1:
So if you can get GLSurfaceView
working with the camera preview as in this question then you can make 3 more copies simply by adding 6 more polygons. Let me explain how they are layed out. vtmp
and ttmp
describe the vector coordinates and texture coordinates, respectively, of two triangles, in a GL_TRIANGLE_STRIP
form:
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
};
Step 1: Let's change the primitive type to a GL_TRIANGLES
, because this is going to be difficult with a GL_TRIANGLE_STRIP
:
//This also includes a fix for the left/right inversion:
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
};
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.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6); //Careful: Multiple changes on this line
(...)
If Step 1 went well, then let's add the extra triangles in Step 2:
float[] vtmp = {
//Triangle 1:
-1.0f, 0.0f,
-1.0f, 1.0f,
0.0f, 0.0f,
//Triangle 2:
0.0f, 0.0f,
-1.0f, 1.0f,
0.0f, 1.0f,
//Triangle 3:
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
//Triangle 4:
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
//Triangle 5:
0.0f, -1.0f,
0.0f, 0.0f,
1.0f, -1.0f,
//Triangle 6:
1.0f, -1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
//Triangle 7:
-1.0f, -1.0f,
-1.0f, 0.0f,
0.0f, -1.0f,
//Triangle 8:
0.0f, -1.0f,
-1.0f, 0.0f,
0.0f, 0.0f
};
float[] ttmp = {
//This is the same as in Step 1, but duplicated 4 times over:
//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.glDrawArrays(GLES20.GL_TRIANGLES, 0, 24);
(...)
来源:https://stackoverflow.com/questions/59524927/how-to-create-multiple-camera2-previews-in-most-efficient-way