Android(安卓)使用Camera2 调用摄像头显示预览与拍照
16lz
2022-03-16
Android Camera2 调用摄像头显示预览与拍照
- CameraFragment.java
- MainActivity.java
CameraFragment.java
package com.example.customcamaratest;import android.Manifest;import android.content.Context;import android.content.pm.PackageManager;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Camera;import android.graphics.ImageFormat;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.hardware.camera2.CameraAccessException;import android.hardware.camera2.CameraCaptureSession;import android.hardware.camera2.CameraCharacteristics;import android.hardware.camera2.CameraDevice;import android.hardware.camera2.CameraManager;import android.hardware.camera2.CaptureRequest;import android.media.Image;import android.media.ImageReader;import android.os.Looper;import android.util.SparseIntArray;import android.view.LayoutInflater;import android.view.Surface;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.os.Build;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.widget.Toast;import androidx.annotation.NonNull;import androidx.annotation.Nullable;import androidx.annotation.RequiresApi;import androidx.core.app.ActivityCompat;import androidx.fragment.app.Fragment;import java.nio.ByteBuffer;import java.util.Arrays;public class CameraFragment extends Fragment { public static final int REQUEST_CAMERA_CODE = 100; public static final String PACKAGE = "package"; private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); ///为了照片竖直显示 static { ORIENTATIONS.append(Surface.ROTATION_0,90); ORIENTATIONS.append(Surface.ROTATION_90,0); ORIENTATIONS.append(Surface.ROTATION_180,270); ORIENTATIONS.append(Surface.ROTATION_270,180); } private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder; private ImageView iv_show; private ImageView mCapture; private CameraManager mCameraManager; private Handler childHandler, mainHandler; private String mCameraID;//摄像头Id 0 为 后 1 为前 private ImageReader mImageReader; private CameraCaptureSession mCameraCaptureSession; private CameraDevice mCameraDevice; private Image image; /** * 摄像头创建监听 */ private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice cameraDevice) {//打卡摄像头 mCameraDevice = cameraDevice; //开启预览 takePreview(); } @Override public void onDisconnected(CameraDevice cameraDevice) {//关闭摄像头 if (null != mCameraDevice){ mCameraDevice.close(); CameraFragment.this.mCameraDevice = null; } } @Override public void onError(CameraDevice cameraDevice, int i) { Toast.makeText(getContext(), "摄像头开启失败", Toast.LENGTH_SHORT).show(); } }; public static CameraFragment newInstance(){ return new CameraFragment(); } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_camera2,container,false); initView(root); initListener(); return root; } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onResume() { super.onResume(); } /** * 初始化 */ private void initView(View root){ iv_show = (ImageView)root.findViewById(R.id.iv_show_camera2); //mSurfaceView mSurfaceView = (SurfaceView)root.findViewById(R.id.surface_view_camera2); mCapture = (ImageView)root.findViewById(R.id.capture); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.setKeepScreenOn(true); //mSurfaceView添加回调 mSurfaceHolder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { //初始化camera initCamera2(); } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { } @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { //释放camera资源 if (null != mCameraDevice){ mCameraDevice.close(); CameraFragment.this.mCameraDevice = null; } } }); } /** * 初始化Camera2 */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private void initCamera2(){ HandlerThread handlerThread = new HandlerThread("Camera2"); handlerThread.start(); childHandler = new Handler(handlerThread.getLooper()); mainHandler = new Handler(Looper.getMainLooper()); mCameraID = "" + CameraCharacteristics.LENS_FACING_FRONT; mImageReader = ImageReader.newInstance(1080,1920, ImageFormat.JPEG,1); mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {//在这处理得到的照片 @Override public void onImageAvailable(ImageReader imageReader) {// if (image != null){// image = null;// } image = imageReader.acquireNextImage(); ByteBuffer buffer = image.getPlanes()[0].getBuffer(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes);//由缓冲区写入字节数组 final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes,0,bytes.length); if (bitmap != null){ iv_show.setImageBitmap(bitmap); image.close(); } } },mainHandler); //获取摄像头管理 mCameraManager = (CameraManager)getContext().getSystemService(Context.CAMERA_SERVICE); try { if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){ requestPermissions(new String[]{Manifest.permission.CAMERA},REQUEST_CAMERA_CODE); }else { //打开摄像头 mCameraManager.openCamera(mCameraID,stateCallback,mainHandler); } }catch (CameraAccessException e){ e.printStackTrace(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CAMERA_CODE){ if (grantResults[0] == PackageManager.PERMISSION_GRANTED){ try { mCameraManager.openCamera(mCameraID,stateCallback,mainHandler); }catch (CameraAccessException e){ e.printStackTrace(); }catch (SecurityException e){ e.printStackTrace(); } }else { Toast.makeText(getContext(),"Permission Denied",Toast.LENGTH_SHORT).show(); } } } /** * 开始预览 */ private void takePreview() { try{ //创建预览需要的CaptureRequest.Builder final CaptureRequest.Builder previewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); //将SurfceView的surface作为CaptureRequest.Builder的目标 previewRequestBuilder.addTarget(mSurfaceHolder.getSurface()); //创建CameraCaptureSession,该对象负责管理处理预览请求和拍照请求 mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface(), mImageReader.getSurface()), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession cameraCaptureSession) { if (null == mCameraDevice)return; //摄像头已经准备好后显示预览 mCameraCaptureSession = cameraCaptureSession; try { //自动对焦 previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); //打卡闪光灯 previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); //显示预览 CaptureRequest previewRequest = previewRequestBuilder.build(); mCameraCaptureSession.setRepeatingRequest(previewRequest,null,childHandler);// 进行预览 }catch (CameraAccessException e){ e.printStackTrace(); } } @Override public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { Toast.makeText(getContext(), "配置失败", Toast.LENGTH_SHORT).show(); } },childHandler); }catch (CameraAccessException e){ e.printStackTrace(); } } private void takePicture(){ if (mCameraDevice == null)return; //创建拍照所需要的CaptureRequestBuilder final CaptureRequest.Builder captureResquestBuilder; try{ captureResquestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); //将imageReader的surface作为CaptureRequest.Builder的目标 captureResquestBuilder.addTarget(mImageReader.getSurface()); //自动对焦 captureResquestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); //自动曝光 captureResquestBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); //获取手机方向 int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation(); //根据设备方向计算设置照片的方向 captureResquestBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation)); //拍照 CaptureRequest mCaptureRequest = captureResquestBuilder.build(); mCameraCaptureSession.capture(mCaptureRequest,null,childHandler); }catch (CameraAccessException e){ e.printStackTrace(); } } private void initListener(){ mCapture.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { takePicture(); } }); }}
MainActivity.java
package com.example.customcamaratest;import androidx.appcompat.app.AppCompatActivity;import androidx.fragment.app.FragmentTransaction;import android.app.Activity;import android.os.Bundle;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); CameraFragment cameraFragment = (CameraFragment)getSupportFragmentManager().findFragmentById(R.id.contentFrame); if (cameraFragment ==null){ cameraFragment = CameraFragment.newInstance(); FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.add(R.id.contentFrame,cameraFragment); fragmentTransaction.commit(); } }}
更多相关文章
- Android(安卓)照相机的实例应用
- Android相机开发那些坑
- Android中调用摄像头并实现对焦拍照
- Android(安卓)ListView 滚动加载数据
- 简单的 Android(安卓)拍照并显示以及获取路径后上传
- OpenCV 连接 Android(安卓)IP摄像头
- android.hardware.Camera翻译
- Android(安卓)调用相册 拍照 实现系统控件缩放 切割图片
- Android(安卓)摄像头后台采集