添加权限

  

逻辑实现

import android.Manifest;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import android.content.pm.PackageManager;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.ImageFormat;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.PorterDuff;import android.graphics.Rect;import android.graphics.SurfaceTexture;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.CameraMetadata;import android.hardware.camera2.CaptureRequest;import android.hardware.camera2.CaptureResult;import android.hardware.camera2.TotalCaptureResult;import android.hardware.camera2.params.Face;import android.hardware.camera2.params.StreamConfigurationMap;import android.media.Image;import android.media.ImageReader;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.support.annotation.NonNull;import android.support.v4.app.ActivityCompat;import android.util.Log;import android.util.Size;import android.util.SparseIntArray;import android.view.Surface;import android.view.TextureView;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import com.yl.fecedetectdemo.R;import java.nio.ByteBuffer;import java.util.Arrays;public class MainActivity extends Activity {    private static void Log(String message) {        Log.i(MainActivity.class.getName(), message);    }    //为了使照片竖直显示    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 TextureView cView;//用于相机预览    private TextureView rView;//用于标注人脸    private ImageView imageView;//拍照照片显示    private TextView textView;    private Button btnFront;    private Button btnBack;    private Button btnClose;    private Button btnCapture;    private Surface previewSurface;//预览Surface    private ImageReader cImageReader;    private Surface captureSurface;//拍照Surface    HandlerThread cHandlerThread;//相机处理线程    Handler cHandler;//相机处理    CameraDevice cDevice;    CameraCaptureSession cSession;    CameraDevice.StateCallback cDeviceOpenCallback = null;//相机开启回调    CaptureRequest.Builder previewRequestBuilder;//预览请求构建    CaptureRequest previewRequest;//预览请求    CameraCaptureSession.CaptureCallback previewCallback;//预览回调    CaptureRequest.Builder captureRequestBuilder;    CaptureRequest captureRequest;    CameraCaptureSession.CaptureCallback captureCallback;    int[] faceDetectModes;    // Rect rRect;//相机成像矩形    Size cPixelSize;//相机成像尺寸    int cOrientation;    Size captureSize;    boolean isFront;    Paint pb;    Bitmap bitmap;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_face);        //GlobalExceptionHandler catchHandler = GlobalExceptionHandler.getInstance();        //catchHandler.init(this.getApplication());        initVIew();    }    /**     * 初始化界面     */    private void initVIew() {        cView = (TextureView) findViewById(R.id.cView);        rView = (TextureView) findViewById(R.id.rView);        imageView = (ImageView) findViewById(R.id.imageView);        textView = (TextView) findViewById(R.id.textView);        btnFront = (Button) findViewById(R.id.btnFront);        btnBack = (Button) findViewById(R.id.btnBack);        btnClose = (Button) findViewById(R.id.btnClose);        btnCapture = (Button) findViewById(R.id.btnCapture);        //隐藏背景色,以免标注人脸时挡住预览画面        rView.setAlpha(0.9f);        btnFront.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                openCamera(true);            }        });        btnBack.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                openCamera(false);            }        });        btnClose.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                closeCamera();            }        });        btnCapture.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                executeCapture();            }        });        //TODO 摄像头静音尝试// try {// Class<?> cClass = Class.forName("android.hardware.Camera");// Method mOpen = cClass.getDeclaredMethod("open");// Object nCamera = mOpen.invoke(null);// Method mDisableShutterSound = cClass.getDeclaredMethod("disableShutterSound");// mDisableShutterSound.invoke(nCamera);// Method mRelease = cClass.getDeclaredMethod("release");// mRelease.invoke(nCamera);// } catch (ClassNotFoundException e) {// Log(Log.getStackTraceString(e));// } catch (NoSuchMethodException e) {// Log(Log.getStackTraceString(e));// } catch (IllegalAccessException e) {// Log(Log.getStackTraceString(e));// } catch (InvocationTargetException e) {// Log(Log.getStackTraceString(e));// }    }    @SuppressLint("NewApi")    private void openCamera(boolean isFront) {        closeCamera();        this.isFront = isFront;        String cId = null;        if (isFront) {            cId = CameraCharacteristics.LENS_FACING_BACK + "";        } else {            cId = CameraCharacteristics.LENS_FACING_FRONT + "";        }        CameraManager cManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);        try {            //获取开启相机的相关参数            CameraCharacteristics characteristics = cManager.getCameraCharacteristics(cId);            StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);            Size[] previewSizes = map.getOutputSizes(SurfaceTexture.class);//获取预览尺寸            Size[] captureSizes = map.getOutputSizes(ImageFormat.JPEG);//获取拍照尺寸            cOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);//获取相机角度            Rect cRect = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);//获取成像区域            cPixelSize = characteristics.get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE);//获取成像尺寸,同上            //可用于判断是否支持人脸检测,以及支持到哪种程度            faceDetectModes = characteristics.get(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);//支持的人脸检测模式            int maxFaceCount = characteristics.get(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT);//支持的最大检测人脸数量            //此处写死640*480,实际从预览尺寸列表选择            Size sSize = new Size(640,480);//previewSizes[0];            //设置预览尺寸(避免控件尺寸与预览画面尺寸不一致时画面变形)            cView.getSurfaceTexture().setDefaultBufferSize(sSize.getWidth(),sSize.getHeight());            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {                // TODO: Consider calling                //    ActivityCompat#requestPermissions                // here to request the missing permissions, and then overriding                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,                //                                          int[] grantResults)                // to handle the case where the user grants the permission. See the documentation                // for ActivityCompat#requestPermissions for more details.                Toast.makeText(this,"请授予摄像头权限",Toast.LENGTH_LONG).show();                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA}, 0);                return;            }            //根据摄像头ID,开启摄像头            try {                cManager.openCamera(cId, getCDeviceOpenCallback(), getCHandler());            } catch (CameraAccessException e) {                Log(Log.getStackTraceString(e));            }        } catch (CameraAccessException e) {            Log(Log.getStackTraceString(e));        }    }    @SuppressLint("NewApi")    private void closeCamera(){        if (cSession != null){            cSession.close();            cSession = null;        }        if (cDevice!=null){            cDevice.close();            cDevice = null;        }        if (cImageReader != null) {            cImageReader.close();            cImageReader = null;            captureRequestBuilder = null;        }        if(cHandlerThread!=null){            cHandlerThread.quitSafely();            try {                cHandlerThread.join();                cHandlerThread = null;                cHandler = null;            } catch (InterruptedException e) {                Log(Log.getStackTraceString(e));            }        }    }    /**     * 初始化并获取相机开启回调对象。当准备就绪后,发起预览请求     */    @SuppressLint("NewApi")    private CameraDevice.StateCallback getCDeviceOpenCallback(){        if(cDeviceOpenCallback == null){            cDeviceOpenCallback = new CameraDevice.StateCallback() {                @Override                public void onOpened(@NonNull CameraDevice camera) {                    cDevice = camera;                    try {                        //创建Session,需先完成画面呈现目标(此处为预览和拍照Surface)的初始化                        camera.createCaptureSession(Arrays.asList(getPreviewSurface(), getCaptureSurface()), new CameraCaptureSession.StateCallback() {                            @Override                            public void onConfigured(@NonNull CameraCaptureSession session) {                                cSession = session;                                //构建预览请求,并发起请求                                Log("[发出预览请求]");                                try {                                    session.setRepeatingRequest(getPreviewRequest(), getPreviewCallback(), getCHandler());                                } catch (CameraAccessException e) {                                    Log(Log.getStackTraceString(e));                                }                            }                            @Override                            public void onConfigureFailed(@NonNull CameraCaptureSession session) {                                session.close();                            }                        }, getCHandler());                    } catch (CameraAccessException e) {                        Log(Log.getStackTraceString(e));                    }                }                @Override                public void onDisconnected(@NonNull CameraDevice camera) {                    camera.close();                }                @Override                public void onError(@NonNull CameraDevice camera, int error) {                    camera.close();                }            };        }        return cDeviceOpenCallback;    }    /**     * 初始化并获取相机线程处理     * @return     */    private Handler getCHandler(){        if(cHandler==null){            //单独开一个线程给相机使用            cHandlerThread = new HandlerThread("cHandlerThread");            cHandlerThread.start();            cHandler = new Handler(cHandlerThread.getLooper());        }        return cHandler;    }    /**     * 获取支持的最高人脸检测级别     * @return     */    private int getFaceDetectMode(){        if(faceDetectModes == null){            return CaptureRequest.STATISTICS_FACE_DETECT_MODE_FULL;        }else{            return faceDetectModes[faceDetectModes.length-1];        }    }/*---------------------------------预览相关---------------------------------*/    /**     * 初始化并获取预览回调对象     * @return     */    @SuppressLint("NewApi")    private CameraCaptureSession.CaptureCallback getPreviewCallback (){        if(previewCallback == null){            previewCallback = new CameraCaptureSession.CaptureCallback(){                public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {                    MainActivity.this.onCameraImagePreviewed(result);                }            };        }        return previewCallback;    }    /**     * 生成并获取预览请求     * @return     */    @SuppressLint("NewApi")    private CaptureRequest getPreviewRequest(){        previewRequest = getPreviewRequestBuilder().build();        return previewRequest;    }    /**     * 初始化并获取预览请求构建对象,进行通用配置,并每次获取时进行人脸检测级别配置     * @return     */    @SuppressLint("NewApi")    private CaptureRequest.Builder getPreviewRequestBuilder(){        if(previewRequestBuilder == null){            try {                previewRequestBuilder = cSession.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);                previewRequestBuilder.addTarget(getPreviewSurface());                previewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);//自动曝光、白平衡、对焦            } catch (CameraAccessException e) {                Log(Log.getStackTraceString(e));            }        }        previewRequestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,getFaceDetectMode());//设置人脸检测级别        return previewRequestBuilder;    }    /**     * 获取预览Surface     * @return     */    private Surface getPreviewSurface(){        if(previewSurface == null){            previewSurface = new Surface(cView.getSurfaceTexture());        }        return previewSurface;    }    /**     * 处理相机画面处理完成事件,获取检测到的人脸坐标,换算并绘制方框     * @param result     */    @SuppressLint({"NewApi", "LocalSuppress"})    private void onCameraImagePreviewed(CaptureResult result){       Face faces[]=result.get(CaptureResult.STATISTICS_FACES);        showMessage(false,"人脸个数:["+faces.length+"]");        Canvas canvas = rView.lockCanvas();        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);//旧画面清理覆盖        if(faces.length>0){            for(int i=0;i
界面代码

<?xml version="1.0" encoding="utf-8"?>                                                                    




更多相关文章

  1. Android--多媒体
  2. Writing code that captures videos on Android(录制视频,带相机
  3. android相机开发setParameters failed错误
  4. 【Android】Eclipse报This version of the rendering library is
  5. Android(安卓)Camera(五)
  6. Android实时监控项目第四篇:后台线程发送预览帧视频数据
  7. 已解决:Android向SD卡存储数据时出现java.io.FileNotFoundExcepti
  8. Android简单实现仿微信选择图片以及拍照(PhotoPicker)
  9. Android(安卓)Studio 视图预览不显示了,

随机推荐

  1. Windows下用Git下载Android SDK源码
  2. 使用代理下载android系统源码和SDK
  3. Android ViewFlow的一个例子
  4. Github开源Android资源整理(十一)优秀项目
  5. Android检查手机是否Root以及应用是否获
  6. Android有趣的爆炸散落动画view:开源Explo
  7. 第2章 IPC机制
  8. Android M新控件之AppBarLayout,Navigatio
  9. android从未安装的apk文件里获取信息(包
  10. Android唤醒、解锁屏幕代码实例