zoukankan      html  css  js  c++  java
  • Android 使用Camera2 调用摄像头显示预览与拍照

    Android Camera2 调用摄像头显示预览与拍照

    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();
            }
        }
    }
    
  • 相关阅读:
    git如何将一个远程仓库的某个分支拉取到当前分支?
    linux下如何检查内核补丁是否符合社区代码规范?
    javascript快速入门20--Cookie
    javascript快速入门19--定位
    javascript快速入门18--样式
    javascript快速入门17--事件
    javascript快速入门16--表格
    javascript快速入门15--表单
    javascript快速入门15--节点
    javascript快速入门14--DOM基础
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13860156.html
Copyright © 2011-2022 走看看