自定义GLSurfaceView+Opengl es实现摄像头预览(完善)

在https://blog.csdn.net/llxyy299/article/details/82705167这里提了两个预留的问题:

1、切换摄像头的时候画面会旋转一下,这个问题下次解决

原因:这是因为我们使用的是opengl的投影矩阵来进行摄像头画面角度的旋转的,在前后摄像头切换的时候,由于他们需要旋转的角度不一样,所以摄像头预览画面投先颠倒一下

解决办法,

第一种:在MyGLSurfaceView里面重新包一层FrameLayout,通过addView的方式添加MyGLSurfaceView,如果摄像头切换,则移除重新添加即可

第二种:将以前的EGLThread停止,再重新启动一个GLThread也可以做到相同的效果,而且还能减少布局的嵌套

这里贴出第一种实现方式,第二种也很简单,这里就不贴了:

package com.leilu.mycamera.camera;

import android.content.Context;
import android.graphics.SurfaceTexture;
import android.util.AttributeSet;
import android.widget.FrameLayout;

import com.leilu.mycamera.EGLThread;
import com.leilu.mycamera.MyGLSurfaceView;

import static android.opengl.GLES10.glClear;
import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
import static android.opengl.GLES20.glClearColor;
import static com.leilu.mycamera.EGLThread.RENDERMODE_WHEN_DIRTY;

/**
 * Created by ll on 2018/9/14.
 */

public class CameraView extends FrameLayout implements EGLThread.OnEGLThreadListener, SurfaceTexture.OnFrameAvailableListener {

    private static final int FRONT_CAMERA_ID = 1;
    private static final int BACK_CAMERA_ID = 0;

    private CameraHelper mCameraHelper;
    private CameraRender mCameraRender;
    private MyGLSurfaceView mGLSurfaceView;
    private int mCameraId = BACK_CAMERA_ID;

    public CameraView(Context context) {
        this(context, null);
    }

    public CameraView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        addGLSurfaceView();
    }

    private void addGLSurfaceView() {
        mGLSurfaceView = new MyGLSurfaceView(getContext());
        addView(mGLSurfaceView);
        mGLSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY);
        mGLSurfaceView.setRenderListener(this);
        mCameraHelper = new CameraHelper();
        mCameraRender = new CameraRender(getContext());
    }

    @Override
    public void onCreate() {
        mCameraRender.init(this);
    }

    @Override
    public void onFrameAvailable(SurfaceTexture surfaceTexture) {
        mGLSurfaceView.requestRender();
    }

    @Override
    public void onSurfaceChanged(Object surface, int width, int height) {
        mCameraRender.setViewPort(width, height);
        SurfaceTexture surfaceTexture = mCameraRender.getSurfaceTexture();
        if (surfaceTexture != null) {
            mCameraHelper.init(mCameraId, width, height, surfaceTexture);
            open();
        }
    }

    @Override
    public void onDrawFrame() {
        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(0, 0, 0, 1);
        mCameraRender.draw();
    }

    public void open() {
        if (mCameraRender != null && mCameraHelper != null) {
            mCameraRender.setProjectionMatrix(mCameraId == 0);
            mCameraHelper.startPreview();
        }
    }

    public void close() {
        if (mCameraHelper != null)
            mCameraHelper.stopPreview();
    }

    @Override
    protected void onDetachedFromWindow() {
        release();
        super.onDetachedFromWindow();
    }

    private void release() {
        removeAllViews();
        if (mCameraHelper != null) {
            mCameraHelper.release();
            mCameraHelper = null;
        }
        if (mCameraRender != null) {
            mCameraRender.release();
            mCameraRender = null;
        }
    }

    public void switchCamera() {
        if (mCameraId == BACK_CAMERA_ID) {
            mCameraId = FRONT_CAMERA_ID;
        } else {
            mCameraId = BACK_CAMERA_ID;
        }
        release();
        addGLSurfaceView();
    }
}

 

你可能感兴趣的:(OpenglES)