Camera 、Camera2 预览 和 二次预览
2019-03-12 本文已影响0人
天敦敦
1、创建CameraApiInterface,供Activity和Camera实现
public interface CameraApiInterface {
interface CameraNeed {
<V extends View> void init (Context context, V view , CameraCallBack callBack);
void openCamera (int index);
void closeCamera ();
}
interface CameraCallBack {
void frameChange (byte[] data, int width, int height);
}
}
2、编写Camera Api的调用
public class Camera1Api implements CameraApiInterface.CameraNeed, SurfaceHolder.Callback,
Camera.PreviewCallback {
private Context mContext;
private SurfaceView mSurfaceView;
private CameraApiInterface.CameraCallBack mCallBack;
private Camera mCamera;
private int mCameraIndex;
/**
* 预览尺寸
*/
private Size mSize = new Size(1280,720);
private boolean mCameraOpen = false;
@Override
public <V extends View> void init(Context context, V view, CameraApiInterface.CameraCallBack callBack) {
mCallBack = callBack;
mContext = context;
mSurfaceView = (SurfaceView) view;
}
@Override
public void openCamera(int index) {
mCameraIndex = index;
mSurfaceView.getHolder().addCallback(this);
}
@Override
public void closeCamera() {
if ( mSurfaceView != null ) {
mSurfaceView.getHolder().removeCallback (this);
}
if ( mCamera != null ) {
mCamera.setPreviewCallback ( null );
mCamera.stopPreview ();
mCamera.release ();
mCamera = null;
mCameraOpen = false;
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = getCameraInstance();
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
mCamera.setPreviewCallback(this);
} catch(IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
int rotation = getDisplayOrientation(); //获取当前窗口方向
mCamera.setDisplayOrientation(rotation); //设定相机显示方向
try {
if (null != mCamera) {
mCamera.setPreviewDisplay(holder);
if (mCameraOpen) {
mCamera.startPreview();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (holder!= null) {
holder.removeCallback(this);
}
}
private android.hardware.Camera getCameraInstance(){
android.hardware.Camera c = null;
try {
c = android.hardware.Camera.open(mCameraIndex);
android.hardware.Camera.Parameters p = c.getParameters();
p.setPreviewFormat( ImageFormat.NV21);
int imageWidth = mSize.getWidth();
int imageHeight = mSize.getHeight();
p.setPreviewSize(imageWidth, imageHeight);
p.setPictureFormat( ImageFormat.NV21);
p.setPictureSize(imageWidth, imageHeight);
p.setZoom(0);
int frameRate = 30;
p.setPreviewFrameRate(frameRate);
int cameraRotation = 0;
p.setRotation(cameraRotation);
c.setParameters ( p );
} catch(Exception e){
e.printStackTrace();
}
return c;
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
mCallBack.frameChange(data, camera.getParameters().getPictureSize().width,
camera.getParameters().getPictureSize().height);
}
// 获取当前窗口管理器显示方向
private int getDisplayOrientation(){
WindowManager windowManager = ((Activity)mContext).getWindowManager();
Display display = windowManager.getDefaultDisplay();
int rotation = display.getRotation();
int degrees = 0;
switch (rotation){
case Surface.ROTATION_0:
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
android.hardware.Camera.CameraInfo camInfo = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(
android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK, camInfo);
return (camInfo.orientation - degrees + 360) % 360;
}
}
3、Activity 调用
public class CameraShowActivity extends Activity implements CameraApiInterface.CameraCallBack {
CameraApiInterface.CameraNeed cameraNeed;
private YuvGLRenderer mGLRenderer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_show);
GLSurfaceView glSurfaceView = findViewById(R.id.gl_surface_view);
mGLRenderer = new YuvGLRenderer(glSurfaceView, 1280, 720);
SurfaceView surfaceView = findViewById(R.id.surface_view);
cameraNeed = new Camera1Api();
cameraNeed.init(this, surfaceView, this);
}
@Override
protected void onResume() {
super.onResume();
cameraNeed.openCamera(1);
}
@Override
protected void onPause() {
super.onPause();
cameraNeed.closeCamera();
}
@Override
public void frameChange(byte[] data, int width, int height) {
mGLRenderer.nv21Update(data, width, height);
}
}
4、xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="1280px"
android:layout_height="720px" />
<android.opengl.GLSurfaceView
android:id="@+id/gl_surface_view"
android:layout_width="1280px"
android:layout_height="720px" />
</LinearLayout>
5、Camera2 预览
public class Camera2Api implements CameraApiInterface.CameraNeed, SurfaceHolder.Callback {
private SurfaceHolder mSurfaceHolder;
private ImageReader mImageReader;
private CameraCaptureSession mCameraCaptureSession;
private CameraDevice mCameraDevice;
private Context mContext;
private CameraApiInterface.CameraCallBack mCameraCallBack;
private int mCameraIndex;
private int mWidth = 1280;
private int mHeight = 720;
private Handler mChildHandler;
@Override
public <V extends View> void init(Context context, V view, CameraApiInterface.CameraCallBack callBack) {
mContext = context;
mCameraCallBack = callBack;
mSurfaceHolder = ((SurfaceView)view).getHolder();
mSurfaceHolder.setKeepScreenOn(true);
}
@Override
public void openCamera(int index) {
mCameraIndex = index;
mSurfaceHolder.addCallback(this);
}
@Override
public void closeCamera() {
if (mSurfaceHolder != null) {
mSurfaceHolder.removeCallback(this);
}
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
if (null != mCameraCaptureSession) {
mCameraCaptureSession.close();
mCameraCaptureSession = null;
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
initCamera();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
}
@SuppressLint("MissingPermission")
private void initCamera() {
HandlerThread handlerThread = new HandlerThread("Camera2");
handlerThread.start();
mChildHandler = new Handler(handlerThread.getLooper());
Handler mainHandler = new Handler(mContext.getMainLooper());
mImageReader = ImageReader.newInstance(mWidth, mHeight,
ImageFormat.YUV_420_888, 1);
mImageReader.setOnImageAvailableListener(new ImageReader
.OnImageAvailableListener() { // 可以在这里处理拍照得到的临时照片 例如,写入本地
@Override
public void onImageAvailable(ImageReader reader) {
}
}, mainHandler);
CameraManager mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
try {
mCameraManager.openCamera(String.valueOf(mCameraIndex), mStateCallback, mainHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 摄像头创建监听
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) { // 打开摄像头
mCameraDevice = camera;
// 开启预览
createPreview();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) { // 关闭摄像头
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
}
@Override
public void onError(@NonNull CameraDevice camera, int error) { // 发生错误
Toast.makeText(mContext, "摄像头开启失败", Toast.LENGTH_SHORT).show();
}
};
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void createPreview() {
try {
// 创建预览需要的CaptureRequest.Builder
final CaptureRequest.Builder previewRequestBuilder = mCameraDevice
.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// 将SurfaceView的surface作为CaptureRequest.Builder的目标
previewRequestBuilder.addTarget(mSurfaceHolder.getSurface());
// previewRequestBuilder.addTarget(mImageReader.getSurface());
// 创建CameraCaptureSession,该对象负责管理处理预览请求
mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface()),
new CCSStateCallback(previewRequestBuilder),
mChildHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
class CCSStateCallback extends CameraCaptureSession.StateCallback {
private CaptureRequest.Builder previewRequestBuilder;
CCSStateCallback(CaptureRequest.Builder previewRequestBuilder) {
this.previewRequestBuilder = previewRequestBuilder;
}
@Override
public void onConfigured(CameraCaptureSession session) {
if (null == mCameraDevice) {
return;
}
// 当摄像头已经准备好时,开始显示预览
mCameraCaptureSession = session;
try {
// 自动对焦
previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 显示预览
CaptureRequest previewRequest = previewRequestBuilder.build();
mCameraCaptureSession.setRepeatingRequest(previewRequest,
null, mChildHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
Toast.makeText(mContext, "配置失败", Toast.LENGTH_SHORT).show();
}
}
}