package com.kernal.passportreader.sdk.utils; import android.content.Context; import android.graphics.Point; import android.hardware.Camera; import android.view.Display; import android.view.Surface; import android.view.WindowManager; import java.util.Collection; import java.util.List; import java.util.regex.Pattern; import kernal.idcard.camera.CardOcrRecogConfigure; public final class CameraConfigurationManager { private static final int TEN_DESIRED_ZOOM = 27; private static final Pattern COMMA_PATTERN = Pattern.compile(","); private final Context mContext; private Point mScreenResolution; private Point mCameraResolution; private Point mPreviewResolution; public CameraConfigurationManager(Context context) { mContext = context; } public void initFromCameraParameters(Camera camera) { Camera.Parameters parameters = camera.getParameters(); if (CameraConfigurationManager.autoFocusAble(camera)) { parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); } mScreenResolution = CardScreenUtil.getScreenResolution(mContext); Point screenResolutionForCamera = new Point(); screenResolutionForCamera.x = mScreenResolution.x; screenResolutionForCamera.y = mScreenResolution.y; // preview size is always something like 480*320, other 320*480 int orientation = CardScreenUtil.getScreenOrientation(mContext); if (orientation == CardScreenUtil.ORIENTATION_PORTRAIT) { screenResolutionForCamera.x = mScreenResolution.y; screenResolutionForCamera.y = mScreenResolution.x; } if ((float) screenResolutionForCamera.x / screenResolutionForCamera.y == 0.75) { screenResolutionForCamera.x = 1280; screenResolutionForCamera.y = 960; // WriteUtil.writeLog("设置的目标分辨率1280X960"); mPreviewResolution = getPreviewResolution(parameters, screenResolutionForCamera); }/* else if((float) screenResolutionForCamera.x/screenResolutionForCamera.y<0.5625){ screenResolutionForCamera.x=1440; screenResolutionForCamera.y=720; WriteUtil.writeLog("设置的目标分辨率1440X720"); mPreviewResolution = getPreviewResolution(parameters, screenResolutionForCamera); }*/ else { // WriteUtil.writeLog("设置的目标分辨率1280X720"); if (CardOcrRecogConfigure.getInstance().nMainId == 2010) { /** * 算法强烈要求 * 由于印度尼西亚身份证识别 * 需要高清图片所以设置成1080P */ screenResolutionForCamera.x = 1920; screenResolutionForCamera.y = 1080; } else { screenResolutionForCamera.x = 1280; screenResolutionForCamera.y = 720; } mPreviewResolution = getPreviewResolution(parameters, screenResolutionForCamera); } // WriteUtil.writeLog("获取的预览分辨率为"+mPreviewResolution.x+"X"+mPreviewResolution.y); if (orientation == CardScreenUtil.ORIENTATION_PORTRAIT) { mCameraResolution = new Point(mPreviewResolution.y, mPreviewResolution.x); } else { mCameraResolution = mPreviewResolution; } } /** * 获取对焦方式 * * @param camera * @return */ public static boolean autoFocusAble(Camera camera) { List supportedFocusModes = camera.getParameters().getSupportedFocusModes(); String focusMode = findSettableValue(supportedFocusModes, Camera.Parameters.FOCUS_MODE_AUTO); return focusMode != null; } public Point getCameraResolution() { return mCameraResolution; } public Point getmPreviewResolution() { return mPreviewResolution; } /** * 设置相机的参数 * * @param camera */ public void setDesiredCameraParameters(Camera camera) { Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(mPreviewResolution.x, mPreviewResolution.y); setZoom(parameters); camera.setDisplayOrientation(getDisplayOrientation()); camera.setParameters(parameters); } /** * 开启闪光灯 * * @param camera */ public void openFlashlight(Camera camera) { doSetTorch(camera, true); } /** * 关闭闪光灯 * * @param camera */ public void closeFlashlight(Camera camera) { doSetTorch(camera, false); } private void doSetTorch(Camera camera, boolean newSetting) { Camera.Parameters parameters = camera.getParameters(); String flashMode; /** 是否支持闪光灯 */ if (newSetting) { flashMode = findSettableValue(parameters.getSupportedFlashModes(), Camera.Parameters.FLASH_MODE_TORCH, Camera.Parameters.FLASH_MODE_ON); } else { flashMode = findSettableValue(parameters.getSupportedFlashModes(), Camera.Parameters.FLASH_MODE_OFF); } if (flashMode != null) { parameters.setFlashMode(flashMode); } camera.setParameters(parameters); } /** * @param supportedValues * @param desiredValues * @return */ private static String findSettableValue(Collection supportedValues, String... desiredValues) { String result = null; if (supportedValues != null) { for (String desiredValue : desiredValues) { if (supportedValues.contains(desiredValue)) { result = desiredValue; break; } } } return result; } /** * 获取旋转角度 * * @return */ public int getDisplayOrientation() { int result; result = SpecialMobileAdaptation.instance.getOrientation(mContext); if (result != -1) { /** * 如果命中特殊机型直接进行返回正确的旋转角度 */ return result; } Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info); WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); int rotation = display.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 == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; } else { result = (info.orientation - degrees + 360) % 360; } return result; } /** * 获取预览分辨率 * * @param parameters * @param screenResolution * @return */ private static Point getPreviewResolution(Camera.Parameters parameters, Point screenResolution) { Point previewResolution = findBestPreviewSizeValue(parameters.getSupportedPreviewSizes(), screenResolution); if (previewResolution == null) { previewResolution = new Point((screenResolution.x >> 3) << 3, (screenResolution.y >> 3) << 3); } return previewResolution; } /** * 获取合适的预览分辨率 * * @param supportSizeList * @param screenResolution * @return */ private static Point findBestPreviewSizeValue(List supportSizeList, Point screenResolution) { int bestX = 0; int bestY = 0; int diff = Integer.MAX_VALUE; for (Camera.Size previewSize : supportSizeList) { int newX = previewSize.width; int newY = previewSize.height; // WriteUtil.writeLog("设备中预览分辨率"+newX+"X"+newY); int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y); if (newDiff == 0) { bestX = newX; bestY = newY; break; } else if (newDiff < diff) { bestX = newX; bestY = newY; diff = newDiff; } } if (bestX > 0 && bestY > 0) { return new Point(bestX, bestY); } return null; } /** * 获取合适的缩放值 * * @param stringValues * @param tenDesiredZoom * @return */ private static int findBestMotZoomValue(CharSequence stringValues, int tenDesiredZoom) { int tenBestValue = 0; for (String stringValue : COMMA_PATTERN.split(stringValues)) { stringValue = stringValue.trim(); double value; try { value = Double.parseDouble(stringValue); } catch (NumberFormatException nfe) { return tenDesiredZoom; } int tenValue = (int) (10.0 * value); if (Math.abs(tenDesiredZoom - value) < Math.abs(tenDesiredZoom - tenBestValue)) { tenBestValue = tenValue; } } return tenBestValue; } /** * 设置缩放 * * @param parameters */ private void setZoom(Camera.Parameters parameters) { String zoomSupportedString = parameters.get("zoom-supported"); if (zoomSupportedString != null && !Boolean.parseBoolean(zoomSupportedString)) { return; } int tenDesiredZoom = TEN_DESIRED_ZOOM; String maxZoomString = parameters.get("max-zoom"); if (maxZoomString != null) { try { int tenMaxZoom = (int) (10.0 * Double.parseDouble(maxZoomString)); if (tenDesiredZoom > tenMaxZoom) { tenDesiredZoom = tenMaxZoom; } } catch (NumberFormatException nfe) { } } String takingPictureZoomMaxString = parameters.get("taking-picture-zoom-max"); if (takingPictureZoomMaxString != null) { try { int tenMaxZoom = Integer.parseInt(takingPictureZoomMaxString); if (tenDesiredZoom > tenMaxZoom) { tenDesiredZoom = tenMaxZoom; } } catch (NumberFormatException nfe) { } } String motZoomValuesString = parameters.get("mot-zoom-values"); if (motZoomValuesString != null) { tenDesiredZoom = findBestMotZoomValue(motZoomValuesString, tenDesiredZoom); } String motZoomStepString = parameters.get("mot-zoom-step"); if (motZoomStepString != null) { try { double motZoomStep = Double.parseDouble(motZoomStepString.trim()); int tenZoomStep = (int) (10.0 * motZoomStep); if (tenZoomStep > 1) { tenDesiredZoom -= tenDesiredZoom % tenZoomStep; } } catch (NumberFormatException nfe) { // continue } } if (maxZoomString != null || motZoomValuesString != null) { parameters.set("zoom", String.valueOf(tenDesiredZoom / 10.0)); } if (takingPictureZoomMaxString != null) { parameters.set("taking-picture-zoom", tenDesiredZoom); } } }