SetPreviewAndCapture.java 10.4 KB
package com.sw.laryngoscope.camera;

import android.app.Activity;
import android.graphics.Rect;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.media.ImageReader;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.TextureView;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import java.util.Arrays;

/**
 * Created by on 2020-01-15.
 * Time will tell.
 * 此类时预览及拍照方法的提供类
 * @description
 */
public class SetPreviewAndCapture {

    public String TAG = "SetPreviewAndCapture";

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

    public static final CaptureRequest.Key<Integer> RK_CONTROL_AIQ_CPROC_ENABLE =
            new CaptureRequest.Key<>("com.rockchip.control.aiq.cproc_enable", int.class);
    public static final CaptureRequest.Key<Integer> RK_CONTROL_AIQ_BRIGHTNESS =
            new CaptureRequest.Key<>("com.rockchip.control.aiq.brightness", int.class);//亮度
    public static final CaptureRequest.Key<Integer> RK_CONTROL_AIQ_CONTRAST =
            new CaptureRequest.Key<>("com.rockchip.control.aiq.contrast", int.class);//对比
    public static final CaptureRequest.Key<Integer> RK_CONTROL_AIQ_SATURATION =
            new CaptureRequest.Key<>("com.rockchip.control.aiq.saturation", int.class);//饱和度
    public static final CaptureRequest.Key<Integer> RK_CONTROL_AIQ_HUE =
            new CaptureRequest.Key<>("com.rockchip.control.aiq.hue", int.class);//色调; 色度
    public static final CaptureRequest.Key<Integer> RK_CONTROL_AIQ_HUE_R =
            new CaptureRequest.Key<>("com.rockchip.control.aiq.huer", int.class);//色调; 色度
    public static final CaptureRequest.Key<Integer> RK_CONTROL_AIQ_HUE_G =
            new CaptureRequest.Key<>("com.rockchip.control.aiq.hueg", int.class);//色调; 色度
    public static final CaptureRequest.Key<Integer> RK_CONTROL_AIQ_HUE_B =
            new CaptureRequest.Key<>("com.rockchip.control.aiq.hueb", int.class);//色调; 色度

    private float mRate = 1;//缩放倍数,默认为1
    private CameraDevice cameraDevice;
    private CameraCaptureSession cameraCaptureSession;
    private CaptureRequest.Builder previewBuilder;
    private CaptureRequest.Builder captureBuilder;
    private TextureView textureView;
    private ImageReader imageReader;
    private Handler handler;
    private Size previewSize;

    Surface mPreviewSurface;
    int rotation;


    public SetPreviewAndCapture(CameraDevice cameraDevice, TextureView textureViewback,
                                ImageReader imageReader, Handler handler, int rotation,
                                Size size) {
        this.cameraDevice = cameraDevice;
        this.textureView = textureViewback;
        this.imageReader = imageReader;
        this.handler = handler;
        this.rotation = rotation;
        this.previewSize = size;
    }

    /**
     * 开启预览的方法
     */
    public void startPreview() {
        try {
            mPreviewSurface = new Surface(textureView.getSurfaceTexture());
            //首先需要构建预览请求
            previewBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            //设置预览输出界面
            previewBuilder.addTarget(mPreviewSurface);
            //创建相机的会话Session
            cameraDevice.createCaptureSession(Arrays.asList(mPreviewSurface, imageReader.getSurface()), stateCallback, handler);
        } catch(CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建Session的状态回调
     */
    private CameraCaptureSession.StateCallback stateCallback = new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(@NonNull CameraCaptureSession session) {
            //会话已经建立,可以开启预览了
            cameraCaptureSession = session;
            //设置自动对焦
            previewBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            //发送预览请求
            try {
                cameraCaptureSession.setRepeatingRequest(previewBuilder.build(), null, handler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
            //开启失败时,关闭会话
            session.close();
            cameraCaptureSession = null;
            cameraDevice.close();
            cameraDevice = null;
        }
    };

    /**
     * 拍摄照片的方法
     */
    public void takePhoto() {
        try {
            //创建拍照请求,设置属性
            captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            //设置拍照的画面
            captureBuilder.addTarget(imageReader.getSurface());
            //设置自动对焦
            //captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            //设置自动曝光
            //captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
            //设置每次拍照都打开闪光灯
            //captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
            //captureBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
            //获取手机方向
            //int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
            //根据设备方向计算照片的方向
            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
            //拍照前需要停止预览
            cameraCaptureSession.stopRepeating();
            //发送拍照请求
            cameraCaptureSession.capture(captureBuilder.build(), captureCallback, handler);
        } catch(CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 拍照请求的回调,返回拍照的结果消息
     */
    private final CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
        @Override
        public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
            super.onCaptureProgressed(session, request, partialResult);
        }

        @Override
        public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
            super.onCaptureCompleted(session, request, result);
            try {
                //停止自动聚焦
                captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
                //重新打开预览
                cameraCaptureSession.setRepeatingRequest(previewBuilder.build(),null,null);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
            super.onCaptureFailed(session, request, failure);
            cameraCaptureSession.close();
            cameraCaptureSession = null;
            cameraDevice.close();
            cameraDevice = null;
        }
    };

    public void setCameraParam(int contrast, int saturation, int brightness, int hue, int hueR, int hueG, int hueB) {
        if ( cameraCaptureSession != null ) {
            Log.e(TAG, "setCameraParam start");
            previewBuilder.set(RK_CONTROL_AIQ_CPROC_ENABLE, 1);
            previewBuilder.set(RK_CONTROL_AIQ_CONTRAST, contrast);
            previewBuilder.set(RK_CONTROL_AIQ_SATURATION, saturation);
            previewBuilder.set(RK_CONTROL_AIQ_HUE, hue);
            previewBuilder.set(RK_CONTROL_AIQ_HUE_R, hueR);
            previewBuilder.set(RK_CONTROL_AIQ_HUE_G, hueG);
            previewBuilder.set(RK_CONTROL_AIQ_HUE_B, hueB);
            previewBuilder.set(RK_CONTROL_AIQ_BRIGHTNESS, brightness);
            CaptureRequest request = previewBuilder.build();
            try {
                cameraCaptureSession.setRepeatingRequest(request, null, handler);
            } catch (Exception e) {
                Log.e(TAG, "setCameraParam error:" + e);
            }
        }
    }

    public void setAWB(int param) {
        previewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, param);
        CaptureRequest request = previewBuilder.build();
        try {
            cameraCaptureSession.setRepeatingRequest(request, null, handler);
        } catch (Exception e) {
            Log.e(TAG, "setWhiteBalance error:" + e);
        }
    }

    public CameraCaptureSession getCameraCaptureSession() {
        return cameraCaptureSession;
    }

    /**
     * 设置缩放的方法
     */
    public void setZoom() {
        //限制可以缩放8次。。。
        if ((mRate - 1) > 1.2) {
            mRate = 1;
        }
        try {
            CaptureRequest.Builder reqBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            // 将SurfaceView的surface作为CaptureRequest.Builder的目标
            reqBuilder.addTarget(mPreviewSurface);
            //这里的Rect表示一个矩形区域,由四条边的坐标组成
            reqBuilder.set(
                    CaptureRequest.SCALER_CROP_REGION,
                    new Rect(0, 0, (int) (previewSize.getWidth() / mRate), (int) (previewSize.getHeight() / mRate)));
            cameraCaptureSession.setRepeatingRequest(reqBuilder.build(), null, handler);
            mRate += 0.15;
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
}