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();        }    }}

更多相关文章

  1. Android(安卓)照相机的实例应用
  2. Android相机开发那些坑
  3. Android中调用摄像头并实现对焦拍照
  4. Android(安卓)ListView 滚动加载数据
  5. 简单的 Android(安卓)拍照并显示以及获取路径后上传
  6. OpenCV 连接 Android(安卓)IP摄像头
  7. android.hardware.Camera翻译
  8. Android(安卓)调用相册 拍照 实现系统控件缩放 切割图片
  9. Android(安卓)摄像头后台采集

随机推荐

  1. Android弹出异常dialog源码分析
  2. 关于 android:sharedUserId="android.uid
  3. Android中隐藏顶部状态栏:
  4. 【android】可放大缩小图片位置点击位置
  5. Android -- Wifi连接流程分析
  6. MMS发送流程 Android2.2
  7. android 颜色搭配表
  8. 19个实用的Android开发工具
  9. Android Pmem
  10. Android后台保活,这里有你需要的所有姿势