使用 kotlin/java 识别 Android 智能手机中的微距相机

问题描述 投票:0回答:1

我正在尝试以编程方式检查 Android 智能手机是否具有微距相机。

尝试了

CameraManager
并通过它发现了相机的不同特性。然后找到微距相机的具体阈值,并将条件置于特性上,以找到微距相机在 Android 智能手机中的可用性。因为就我搜索而言,没有直接的方法来找到微距相机。

val cameraManager =  context?.getSystemService(Context.CAMERA_SERVICE) as? CameraManager

        cameraManager?.cameraIdList?.forEach { cameraId ->
            val characteristics = cameraManager.getCameraCharacteristics(cameraId)
            val lensFacing = characteristics.get(CameraCharacteristics.LENS_FACING)
            val capabilities =
                characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
            capabilities?.let {
                Log.d("macroCameraLog_2", "isMacroCameraSupported: CAMERA_ID $cameraId")
                Log.d("macroCameraLog_2", "isMacroCameraSupported: HARD_WARE_LEVEL $it")
                if (it >= CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3) {
                    Log.d("macroCameraLog_2", "isMacroCameraSupported: TRUE")
                }
            }

        val afModes = characteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES)
            afModes?.let { modes ->
                Log.d("macroCameraLog_3", "isMacroCameraSupported: CAMERA_ID $cameraId")
                Log.d(
                    "macroCameraLog_3",
                    "isMacroCameraSupported: MODES ${formatCharacteristicValue(modes)}"
                )
                if (modes.contains(CameraMetadata.CONTROL_AF_MODE_MACRO)) {
                    Log.d("macroCameraLog_3", "Macro AF mode is supported")
                }

                if (modes.contains(CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE)) {
                    Log.d("macroCameraLog_3", "CONTROL_Macro AF mode is supported")
                }
            }

            if (lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
                // Get the minimum focus distance
                val minFocusDistance =
                    characteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE)
                        ?: return false
                Log.d(
                    "macroCameraLog",
                    "isMacroCameraSupported: Min_Focus -> $minFocusDistance"
                )
                Log.d("macroCameraLog", "isMacroCameraSupported: Camera_ID -> $cameraId")
                // Define a threshold for macro capability (e.g., less than or equal to 0.05 meters or 5 cm)
                if (minFocusDistance in 0.01..0.05) {
                    Log.d(
                        "macroCameraLog",
                        "isMacroCameraSupported: Min_Focus -> $minFocusDistance"
                    )
                    Log.d("macroCameraLog", "isMacroCameraSupported: Camera_ID -> $cameraId")
                }
            }
            // Check if it's a rear camera
            if (lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
                // Check for physical cameras in a multi-camera system
                val physicalCameraIds = characteristics.physicalCameraIds
                if (physicalCameraIds.isNotEmpty()) {
                    for (physicalCameraId in physicalCameraIds) {
                        val physicalCharacteristics =
                            cameraManager.getCameraCharacteristics(physicalCameraId)
                        val physicalFocalLengths =
                            physicalCharacteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)

                        val minFocusDistance =
                            physicalCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE)
                                ?: return false

                        // Define a threshold for macro capability (e.g., less than or equal to 0.05 meters or 5 cm)
                        Log.d(
                            "macroCameraLog",
                            "Physical_isMacroCameraSupported: Camera_ID -> $cameraId"
                        )
                        Log.d(
                            "macroCameraLog",
                            "Physical_isMacroCameraSupported: Min_Focus -> $minFocusDistance"
                        )
                        if (minFocusDistance in 0.01..0.05) {
                            Log.d(
                                "macroCameraLog",
                                "Physical_isMacroCameraSupported: Min_Focus -> $minFocusDistance"
                            )
                            Log.d(
                                "macroCameraLog",
                                "Physical_isMacroCameraSupported: Camera_ID -> $cameraId"
                            )
                        }

                        physicalFocalLengths?.let { focalLengths ->
                            for (focalLength in focalLengths) {
                                // Check for macro lens characteristics
                                if (focalLength in 1.0..2.0) {
                                    // Macro lens found in a multi-camera system
                                    // return true
                                }
                            }
                        }
                    }
                }
            }
        }

我想出的唯一可能的解决方案是根据焦距、硬件水平、最小焦距和自动对焦模式等特定阈值检查微距相机的各种属性。但我没有找到任何可靠的解决方案来检查设备是否有微距摄像头。

java android kotlin android-camera android-camera2
1个回答
0
投票

通过检查各种相机特性(例如焦距、自动对焦模式、硬件级别和最小焦距)来确定设备是否具有微距相机,您就走在正确的道路上。由于Android不提供直接的API来识别微距相机,因此使用这些参数是最好的方法。但是,有几种方法可以改进微距相机的检测机制

fun isMacroCameraSupported(context: Context): Boolean {
val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager

cameraManager.cameraIdList.forEach { cameraId ->
    val characteristics = cameraManager.getCameraCharacteristics(cameraId)

    
    val lensFacing = characteristics.get(CameraCharacteristics.LENS_FACING)
    if (lensFacing != CameraCharacteristics.LENS_FACING_BACK) {
        return@forEach 
    }

   
    val afModes = characteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES)
    if (afModes != null && afModes.contains(CameraMetadata.CONTROL_AF_MODE_MACRO)) {
        Log.d("macroCameraLog", "Macro AF mode is supported for camera ID $cameraId")
    }

   
    val minFocusDistance = characteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE)
    if (minFocusDistance != null && minFocusDistance in 0.01..0.05) {
        Log.d("macroCameraLog", "Macro capability found based on focus distance for camera ID $cameraId")
    }

   
    val focalLengths = characteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
    focalLengths?.let {
        for (focalLength in focalLengths) {
            if (focalLength in 1.0..2.0) {
                Log.d("macroCameraLog", "Macro lens found based on focal length for camera ID $cameraId")
                return true // A macro camera is detected
            }
        }
    }

   
    val hardwareLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
    if (hardwareLevel != null && hardwareLevel >= CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3) {
        Log.d("macroCameraLog", "High-end camera hardware detected for camera ID $cameraId")
    }

   
    val physicalCameraIds = characteristics.physicalCameraIds
    if (physicalCameraIds.isNotEmpty()) {
        physicalCameraIds.forEach { physicalCameraId ->
            val physicalCharacteristics = cameraManager.getCameraCharacteristics(physicalCameraId)
            val physicalFocalLengths = physicalCharacteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
            physicalFocalLengths?.forEach { focalLength ->
                if (focalLength in 1.0..2.0) {
                    Log.d("macroCameraLog", "Macro lens detected in multi-camera system for physical camera ID $physicalCameraId")
                    return true
                }
            }
        }
    }
}

return false // if false -> No macro camera found

}

可以试试这个

© www.soinside.com 2019 - 2024. All rights reserved.