经过前面图片添加滤镜效果的实践,相机预览无非也就是将每一帧的bitmap放到OpenGL中去渲染。
所以很容易想到如下方案:
- 方案A 使用TextureView用于相机预览,TextureView表面再盖上一层GLSurfaceView用与OpenGL ES的渲染输出,从TextureView中获取每一帧的Bitmap交给OpenGL ES渲染到GLSurfaceView上。
很容易看出,方案A的性能并不好,甚至可以说很差,不免反思我们是不是可以去掉一层,因此有了方案B。
- 方案B 从OpenGL ES中生成一个纹理对象,以纹理ID new一个SurfaceTexture回调给外部的相机作为预览的输出,作为OpenGL ES的纹理输入渲染到GLSurfaceView上。
其中方案A使用的Camera2 API,而方案B使用的Camera1 API,整体看来Camera1使用很方便,而Camera2使用起来稍许复杂,但是相对于来说Camera2的实现更规范化。
方案A:
public class Camera2Activity extends AppCompatActivity {
private String TAG = "Camera2Activity";
private Button btShow;
private Button btFilter;
private Button btStart;
private TextureView textureView;
private CameraDevice cameraDevice;
private CameraManager cameraManager;
private CameraCaptureSession cameraCaptureSession;
private CaptureRequest previewRequest;
private Surface preview;
private final int REQUEST_CAMERA_CODE=1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera2);
initView();
}
private GLSurfaceView glSurfaceView;
private FilterRenderer renderer;
private BaseFilter filter;
private int surWidth;
private int surHeight;
public void initView() {
textureView = findViewById(R.id.texture_view);
btFilter = findViewById(R.id.bt_filter);
btStart = findViewById(R.id.bt_start);
btFilter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showFilters();
}
});
btShow = findViewById(R.id.bt_show);
btShow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (glSurfaceView.getVisibility()!=View.VISIBLE) {
glSurfaceView.setVisibility(View.VISIBLE);