Kamera objektifleri ve özellikleri

Not: Bu sayfa, Camera2 paketiyle ilgilidir. Uygulamanız Camera2'den belirli, alt düzey özellikler gerektirmiyorsa CameraX'i kullanmanızı öneririz. Hem CameraX hem de Camera2, Android 5.0 (API düzeyi 21) ve sonraki sürümleri destekler.

Birçok modern Android cihazın önünde, arkasında veya her iki tarafında iki ya da daha fazla kamera bulunur. Her lensin seri çekim, manuel kontrol veya hareket izleme gibi benzersiz özellikleri olabilir. Çek yatırmak için kullanılan bir uygulama yalnızca ilk arka kamerayı kullanabilirken, sosyal medya uygulaması varsayılan olarak ön kamerayı kullanabilir ancak kullanıcılara mevcut tüm lensler arasında geçiş yapma seçeneği sunabilir. Ayrıca seçimlerini de hatırlayabilir.

Bu sayfada, uygulamanızda belirli bir durumda hangi lensi kullanacağınıza karar verebilmeniz için kamera lenslerini ve özelliklerini nasıl listeleyeceğiniz açıklanmaktadır. Aşağıdaki kod snippet'i, tüm kameraların listesini alır ve bunları iterasyona tabi tutar:

try {
    val cameraIdList = cameraManager.cameraIdList // may be empty

    // iterate over available camera devices.
    for (cameraId in cameraIdList) {
        val characteristics = cameraManager.getCameraCharacteristics(cameraId)
        val cameraLensFacing = characteristics.get(CameraCharacteristics.LENS_FACING)
        val cameraCapabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)

        // check if the selected camera device supports basic features
        // ensures backward compatibility with the original Camera API.
        val isBackwardCompatible = cameraCapabilities?.contains(
            CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
        ) ?: false
        // ...
    }
} catch (e: CameraAccessException) {
    e.message?.let { Log.e(TAG, it) }
    // ...
}

cameraLensFacing değişkeni, kameranın cihaz ekranına göre baktığı yönü açıklar ve aşağıdaki değerlerden birine sahiptir:

Lens yönü yapılandırması hakkında daha fazla bilgi için CameraCharacteristics.LENS_FACING sayfasını inceleyin.

Yukarıdaki kod örneğinde yer alan cameraCapabilities değişkeni, kameranın çıkış olarak standart kareler üretip üretemeyeceği (örneğin, yalnızca derinlik sensörü verilerinin aksine) dahil olmak üzere çeşitli özellikler hakkında bilgi içerir. CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE özelliğinin, kameranın listelenen özelliklerinden biri olup olmadığını kontrol edebilirsiniz. Bu özellik, isBackwardCompatible içinde bir işaret olarak depolanır.

Mantıklı varsayılanlar seçin

Uygulamanızda varsayılan olarak belirli bir kamerayı açmak isteyebilirsiniz (mümkünse). Örneğin, selfie uygulamaları genellikle ön kamerayı açarken artırılmış gerçeklik uygulamaları arka kamerayla başlayabilir. Aşağıdaki işlev, belirli bir yöne bakan ilk kamerayı döndürür:

fun getFirstCameraIdFacing(
    cameraManager: CameraManager,
    facing: Int = CameraMetadata.LENS_FACING_BACK
): String? {
    try {
        // Get list of all compatible cameras.
        val cameraIds = cameraManager.cameraIdList.filter {
            val characteristics = cameraManager.getCameraCharacteristics(it)
            val capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)
            capabilities?.contains(
                CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
            ) ?: false
        }

        // Iterate over the list of cameras and return the first one matching desired
        // lens-facing configuration.
        cameraIds.forEach {
            val characteristics = cameraManager.getCameraCharacteristics(it)
            if (characteristics.get(CameraCharacteristics.LENS_FACING) == facing) {
                return it
            }
        }

        // If no camera matched desired orientation, return the first one from the list.
        return cameraIds.firstOrNull()
    } catch (e: CameraAccessException) {
        e.message?.let { Log.e(TAG, it) }
        return null
    }
}

Kamera değiştirme özelliğini etkinleştirme

Birçok kamera uygulaması, kullanıcılara kameralar arasında geçiş yapma seçeneği sunar:

Kamera değiştirme düğmesini gösteren Google Kamera uygulaması arayüzü.
Şekil 1. Google Kamera uygulamasında kamera değiştirme düğmesi

Birçok cihazda aynı yöne bakan birden fazla kamera bulunur. Bazılarında harici USB kameralar bile vardır. Kullanıcılara farklı yönlere bakan kameralar arasında geçiş yapmalarını sağlayan bir kullanıcı arayüzü sunmak için her olası lens yönü yapılandırması için kullanılabilir ilk kamerayı seçin.

Bir sonraki kamerayı seçmek için evrensel bir mantık olmasa da aşağıdaki kod çoğu kullanım alanında çalışır:

fun filterCompatibleCameras(
    cameraIds: Array<String>,
    cameraManager: CameraManager
): List<String> {
    return cameraIds.filter {
        val characteristics = cameraManager.getCameraCharacteristics(it)
        characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)?.contains(
            CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
        ) ?: false
    }
}

fun filterCameraIdsFacing(
    cameraIds: List<String>,
    cameraManager: CameraManager,
    facing: Int
): List<String> {
    return cameraIds.filter {
        val characteristics = cameraManager.getCameraCharacteristics(it)
        characteristics.get(CameraCharacteristics.LENS_FACING) == facing
    }
}

fun getNextCameraId(cameraManager: CameraManager, currCameraId: String? = null): String? {
    // Get all front, back and external cameras in 3 separate lists.
    val cameraIds = filterCompatibleCameras(cameraManager.cameraIdList, cameraManager)
    val backCameras = filterCameraIdsFacing(
        cameraIds, cameraManager, CameraMetadata.LENS_FACING_BACK
    )
    val frontCameras = filterCameraIdsFacing(
        cameraIds, cameraManager, CameraMetadata.LENS_FACING_FRONT
    )
    val externalCameras = filterCameraIdsFacing(
        cameraIds, cameraManager, CameraMetadata.LENS_FACING_EXTERNAL
    )

    // The recommended order of iteration is: all external, first back, first front.
    val allCameras = (
        externalCameras + listOf(
            backCameras.firstOrNull(), frontCameras.firstOrNull()
        )
        ).filterNotNull()

    // Get the index of the currently selected camera in the list.
    val cameraIndex = allCameras.indexOf(currCameraId)

    // The selected camera may not be in the list, for example it could be an
    // external camera that has been removed by the user.
    return if (cameraIndex == -1) {
        // Return the first camera from the list.
        allCameras.getOrNull(0)
    } else {
        // Return the next camera from the list, wrap around if necessary.
        allCameras.getOrNull((cameraIndex + 1) % allCameras.size)
    }
}

Bu kod, birçok farklı yapılandırmaya sahip çok sayıda cihazda çalışır. Uç durumları hesaba katma hakkında daha fazla bilgi için CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA başlıklı makaleyi inceleyin.

Uyumlu uygulamalar oluşturma

Kullanımdan kaldırılan Camera API'yi kullanmaya devam eden uygulamalarda, Camera.getNumberOfCameras() tarafından döndürülen kamera sayısı OEM uygulamasına bağlıdır. Sistemde mantıksal bir çoklu kamera varsa uygulamanın geriye dönük uyumluluğunu korumak için bu yöntem, her mantıksal kamera ve temel fiziksel kamera grubu için yalnızca bir kamera gösterir. Tüm kameraları görmek için Camera2 API'yi kullanın.

Kamera yönleri hakkında daha fazla bilgi için Camera.CameraInfo.orientation başlıklı makaleyi inceleyin.

Genel olarak, tüm kamera orientation'lerini sorgulamak için Camera.getCameraInfo() API'sini kullanın ve kameralar arasında geçiş yapan kullanıcılara her kullanılabilir yön için yalnızca bir kamera gösterin.

Tüm cihaz türlerine uyum sağlama

Uygulamanızın her zaman bir veya iki kamerası olan bir el cihazında çalıştığını varsaymayın. Bunun yerine, uygulama için en uygun kameraları seçin. Belirli bir kameraya ihtiyacınız yoksa seçilen yöne bakan ilk kamerayı seçin. Belirli bir yöne bakan kamera kullanılamıyorsa kullanıcının yolculuğunu farklı bir kamerayla tamamlayıp tamamlayamayacağını değerlendirin. Uygulamanızın belirli cihazlardaki kullanılabilirliğini kamera donanımına göre kısıtlamayın. Harici bir kamera bağlıysa kullanıcı muhtemelen bu kamerayı varsayılan olarak tercih eder.