package com.megvii.idcardlib.util; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.SurfaceTexture; import android.graphics.YuvImage; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.os.Build; import android.view.Surface; import android.widget.RelativeLayout; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * 照相机工具类 */ public class FaceCamera { public Camera mCamera; public int cameraWidth; public int cameraHeight; public int cameraId = 1;//前置摄像头 public FaceCamera() { } /** * 打开相机 */ public Camera openCamera(Activity activity,int cameraId) { try { this.cameraId=cameraId; mCamera = Camera.open(cameraId); CameraInfo cameraInfo = new CameraInfo(); Camera.getCameraInfo(cameraId, cameraInfo); Camera.Parameters params = mCamera.getParameters(); Camera.Size bestPreviewSize = calBestPreviewSize( mCamera.getParameters(), 640, 480); cameraWidth = bestPreviewSize.width; cameraHeight = bestPreviewSize.height; params.setPreviewSize(cameraWidth, cameraHeight); mCamera.setDisplayOrientation(getCameraAngle(activity)); mCamera.setParameters(params); return mCamera; } catch (Exception e) { return null; } } /** * 通过屏幕参数、相机预览尺寸计算布局参数 */ public RelativeLayout.LayoutParams getLayoutParam() { Camera.Size previewSize = mCamera.getParameters().getPreviewSize(); float scale = Math.min(Screen.mWidth * 1.0f / previewSize.height, Screen.mHeight * 1.0f / previewSize.width); int layout_width = (int) (scale * previewSize.height); int layout_height = (int) (scale * previewSize.width); RelativeLayout.LayoutParams layout_params = new RelativeLayout.LayoutParams( layout_width, layout_height); return layout_params; } /** * 如果需要全屏预览,打开下列注释,并注释掉上方getLayoutParam() 方法,openCamera()中调节分辨率到1280 X 720, * 在部分华为机型(存在底部虚拟键的状态栏)需要设置 LivenessActivity 的Theme 为: * android:theme="@android:style/Theme.Holo.NoActionBar.TranslucentDecor" 才可以预览正常。 */ // public RelativeLayout.LayoutParams getLayoutParam() { // float scale = cameraWidth * 1.0f / cameraHeight; // int layout_width = Screen.mWidth; // int layout_height = (int) (layout_width * scale); // if (Screen.mWidth >= Screen.mHeight) { // layout_height = Screen.mHeight; // layout_width = (int) (layout_height / scale); // } // // RelativeLayout.LayoutParams layout_params = new RelativeLayout.LayoutParams( // layout_width, layout_height); // layout_params.addRule(RelativeLayout.CENTER_HORIZONTAL);// 设置照相机水平居中 // return layout_params; // } /** * 开始检测脸 * */ public void actionDetect(Camera.PreviewCallback mActivity) { try { if (mCamera != null) { mCamera.setPreviewCallback(mActivity); } } catch (Exception e) { e.printStackTrace(); } } /** * Start preview. * * @param surfaceTexture the surface texture */ public void startPreview(SurfaceTexture surfaceTexture) { try { if (mCamera != null) { try { mCamera.setPreviewTexture(surfaceTexture); mCamera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } } /** * Close camera. */ public void closeCamera() { try { if (mCamera != null) { mCamera.stopPreview(); mCamera.setPreviewCallback(null); mCamera.release(); mCamera = null; } } catch (Exception e) { e.printStackTrace(); } } /** * 通过传入的宽高算出最接近于宽高值的相机大小 */ private Camera.Size calBestPreviewSize(Camera.Parameters camPara, final int width, final int height) { List<Camera.Size> allSupportedSize = camPara.getSupportedPreviewSizes(); ArrayList<Camera.Size> widthLargerSize = new ArrayList<Camera.Size>(); for (Camera.Size tmpSize : allSupportedSize) { if (tmpSize.width > tmpSize.height) { widthLargerSize.add(tmpSize); } } Collections.sort(widthLargerSize, new Comparator<Camera.Size>() { @Override public int compare(Camera.Size lhs, Camera.Size rhs) { int off_one = Math.abs(lhs.width * lhs.height - width * height); int off_two = Math.abs(rhs.width * rhs.height - width * height); return off_one - off_two; } }); return widthLargerSize.get(0); } public Camera getCameraSafely(int cameraId) { Camera camera = null; try { camera = Camera.open(cameraId); } catch (Exception e) { camera = null; } return camera; } public RelativeLayout.LayoutParams getParams(Camera camera) { Camera.Parameters camPara = camera.getParameters(); Camera.Size bestPreviewSize = calBestPreviewSize(camPara, Screen.mWidth, Screen.mHeight); cameraWidth = bestPreviewSize.width; cameraHeight = bestPreviewSize.height; camPara.setPreviewSize(cameraWidth, cameraHeight); camera.setParameters(camPara); float scale = bestPreviewSize.width / bestPreviewSize.height; RelativeLayout.LayoutParams layoutPara = new RelativeLayout.LayoutParams( (int) (bestPreviewSize.width), (int) (bestPreviewSize.width / scale)); layoutPara.addRule(RelativeLayout.CENTER_HORIZONTAL);// 设置照相机水平居中 return layoutPara; } public Bitmap getBitMap(byte[] data, Camera camera, boolean mIsFrontalCamera) { int width = camera.getParameters().getPreviewSize().width; int height = camera.getParameters().getPreviewSize().height; YuvImage yuvImage = new YuvImage(data, camera.getParameters() .getPreviewFormat(), width, height, null); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); yuvImage.compressToJpeg(new Rect(0, 0, width, height), 80, byteArrayOutputStream); byte[] jpegData = byteArrayOutputStream.toByteArray(); // 获取照相后的bitmap Bitmap tmpBitmap = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length); Matrix matrix = new Matrix(); matrix.reset(); if (mIsFrontalCamera) { matrix.setRotate(-90); } else { matrix.setRotate(90); } tmpBitmap = Bitmap.createBitmap(tmpBitmap, 0, 0, tmpBitmap.getWidth(), tmpBitmap.getHeight(), matrix, true); tmpBitmap = tmpBitmap.copy(Bitmap.Config.ARGB_8888, true); int hight = tmpBitmap.getHeight() > tmpBitmap.getWidth() ? tmpBitmap .getHeight() : tmpBitmap.getWidth(); float scale = hight / 800.0f; if (scale > 1) { tmpBitmap = Bitmap.createScaledBitmap(tmpBitmap, (int) (tmpBitmap.getWidth() / scale), (int) (tmpBitmap.getHeight() / scale), false); } return tmpBitmap; } /** * 获取照相机旋转角度 */ public int getCameraAngle(Activity activity) { int rotateAngle = 90; CameraInfo info = new CameraInfo(); Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } if (info.facing == CameraInfo.CAMERA_FACING_FRONT) { rotateAngle = (info.orientation + degrees) % 360; rotateAngle = (360 - rotateAngle) % 360; // compensate the mirror } else { // back-facing rotateAngle = (info.orientation - degrees + 360) % 360; } return rotateAngle; } public static boolean hasFrontFacingCamera() { final int CAMERA_FACING_BACK = 1; return checkCameraFacing(CAMERA_FACING_BACK); } private static boolean checkCameraFacing(final int facing) { if (getSdkVersion() < Build.VERSION_CODES.GINGERBREAD) { return false; } final int cameraCount = Camera.getNumberOfCameras(); CameraInfo info = new CameraInfo(); for (int i = 0; i < cameraCount; i++) { Camera.getCameraInfo(i, info); if (facing == info.facing) { return true; } } return false; } /** * Gets sdk version. */ public static int getSdkVersion() { return Build.VERSION.SDK_INT; } }