一、camera
mCamera = Camera.open(i)打开并创建一个相机实例
1、可以通过mCamera.setPreviewDisplay(mSurfaceView.getHolder())设置预览载体直接预览
2、也可以通过mCamera.setPreviewTexture(mSurfaceTexture)设置预览载体是一个mSurfaceTexture。mSurfaceTexture要通过OpenGL来创建,可以在SurfaceView中通过自己搭建egl环境来创建,也可以通过封装好egl环境的GLSurfaceView来创建。
二者的区别是通过SurfaceTexture的方式可以对原始数据后台处理后再显示到前台。
(1)通过SurfaceView
void surfaceCreated(SurfaceHolder holder) {
mEglCore = new EglCore(null, EglCore.FLAG_RECORDABLE);
mDisplaySurface = new WindowSurface(mEglCore, holder.getSurface(), false);
mDisplaySurface.makeCurrent(); //自己创建egl
GLES30.glDisable(GLES30.GL_DEPTH_TEST);
GLES30.glDisable(GLES30.GL_CULL_FACE);
int[] textures = new int[1]; //创建纹理
GLES30.glGenTextures(1, textures, 0);
OpenGLUtils.checkGlError("glGenTextures");
int textureId = textures[0];
GLES30.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
OpenGLUtils.checkGlError("glBindTexture " + textureId);
GLES30.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
GLES30.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
GLES30.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
GLES30.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
mInputTexture = textures【0】;
mSurfaceTexture = new SurfaceTexture(mInputTexture);
mSurfaceTexture.setOnFrameAvailableListener(this);
}
(2)通过GLSurfaceView
mMyRender = new MyRender(mApp); //创建GLSurfaceView.Renderer
mGLSurfaceView.setRenderer(mMyRender );
mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
mGLSurfaceView.requestRender();
然后在BeautyRender的onSurfaceCreated方法中创建纹理
int[] textures = new int[1]; //创建纹理
GLES30.glGenTextures(1, textures, 0);
OpenGLUtils.checkGlError("glGenTextures");
int textureId = textures[0];
GLES30.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
OpenGLUtils.checkGlError("glBindTexture " + textureId);
GLES30.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
GLES30.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
GLES30.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
GLES30.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
mInputTexture = textures【0】;
mSurfaceTexture = new SurfaceTexture(mInputTexture);
在onSurfaceChanged中设置预览宽高,在onDrawFrame中执行绘制。
二、camera2
camera2的预览载体必须是Surface,这个Surface可以通过SurfaceView获得
mPreviewSurface = mSurfaceView.getHolder().getSurface();
也可以通过在GLSurfaceView中创建SurfaceTexture获得(具体如一.2.(2)中所述)
mPreviewSurface = new Surface(SurfaceTexture);
通过CaptureRequest.Builder将Surface作为预览目标
mPreviewRequestBuilder.addTarget(surface);
然后将Surface带入创建预览会话
mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == mCameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
mCaptureSession = cameraCaptureSession;
try {
// Auto focus should be continuous for camera preview.
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// Flash is automatically enabled when necessary.
setAutoFlash(mPreviewRequestBuilder);
// Finally, we start displaying the camera preview.
mPreviewRequest = mPreviewRequestBuilder.build();
mCaptureSession.setRepeatingRequest(mPreviewRequest,
mCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(
@NonNull CameraCaptureSession cameraCaptureSession) {
showToast("Failed");
}
}, null
);