Yapılandırma seçenekleri

Kullanım alanı işlemlerinin farklı yönlerini kontrol etmek için her bir CameraX kullanım alanını yapılandırırsınız.

Örneğin, görüntü yakalama kullanım alanında bir hedef en boy oranı ve flaş modu ayarlayabilirsiniz. Aşağıdaki kod bir örnek gösterir:

Kotlin

val imageCapture = ImageCapture.Builder()
    .setFlashMode(...)
    .setTargetAspectRatio(...)
    .build()

Java

ImageCapture imageCapture =
    new ImageCapture.Builder()
        .setFlashMode(...)
        .setTargetAspectRatio(...)
        .build();

Yapılandırma seçeneklerine ek olarak bazı kullanım alanları, kullanım alanı oluşturulduktan sonra API'lerin ayarları dinamik olarak değiştirmesine neden olur. Kullanım alanlarına özel yapılandırma hakkında bilgi edinmek için Önizleme uygulama, Görüntüleri analiz etme ve Görüntü yakalama bölümlerine bakın.

KameraXConfig

CameraX, basitlik açısından çoğu kullanım senaryosuna uygun olan dahili yürütücüler ve işleyiciler gibi varsayılan yapılandırmalara sahiptir. Ancak uygulamanızın özel gereksinimleri varsa veya bu yapılandırmaları özelleştirmeyi tercih ediyorsa CameraXConfig bu amaca yönelik arayüzdür.

Bir uygulama, CameraXConfig ile şunları yapabilir:

Kullanım Modeli

Aşağıdaki prosedürde, CameraXConfig ürününün nasıl kullanılacağı açıklanmaktadır:

  1. Özelleştirilmiş yapılandırmalarınızla bir CameraXConfig nesnesi oluşturun.
  2. CameraXConfig.Provider arayüzünü Application içinde uygulayın ve CameraXConfig nesnenizi getCameraXConfig() içinde döndürün.
  3. Application sınıfınızı AndroidManifest.xml dosyanıza, burada açıklandığı şekilde ekleyin.

Örneğin, aşağıdaki kod örneği CameraX günlük kaydını yalnızca hata mesajlarıyla kısıtlar:

Kotlin

class CameraApplication : Application(), CameraXConfig.Provider {
   override fun getCameraXConfig(): CameraXConfig {
       return CameraXConfig.Builder.fromConfig(Camera2Config.defaultConfig())
           .setMinimumLoggingLevel(Log.ERROR).build()
   }
}

Uygulamanızın, ayarlandıktan sonra CameraX yapılandırmasını bilmesi gerekiyorsa CameraXConfig nesnesinin yerel bir kopyasını saklayın.

Kamera sınırlayıcı

ProcessCameraProvider.getInstance() ilk kez çağrılırken CameraX, cihazdaki kameraların özelliklerini sıralar ve sorgular. CameraX'in donanım bileşenleriyle iletişim kurması gerektiğinden, bu işlem her kamera için (özellikle de düşük teknoloji cihazlarda) çok az zaman alabilir. Uygulamanız cihazda yalnızca varsayılan ön kamera gibi belirli kameraları kullanıyorsa CameraX'i diğer kameraları yok sayacak şekilde ayarlayabilirsiniz. Bu da uygulamanızın kullandığı kameralarda başlatma gecikmesini azaltabilir.

CameraSelector parametresi CameraXConfig.Builder.setAvailableCamerasLimiter()'e geçirilen bir kamerayı filtrelerse CameraX, mevcut kamera yokmuş gibi davranır. Örneğin, aşağıdaki kod uygulamayı yalnızca cihazın varsayılan arka kamerasını kullanacak şekilde sınırlar:

Kotlin

class MainApplication : Application(), CameraXConfig.Provider {
   override fun getCameraXConfig(): CameraXConfig {
       return CameraXConfig.Builder.fromConfig(Camera2Config.defaultConfig())
              .setAvailableCamerasLimiter(CameraSelector.DEFAULT_BACK_CAMERA)
              .build()
   }
}

Sohbetler

CameraX'in derlendiği platform API'lerinin çoğu, bazen yanıt vermesi yüzlerce milisaniye sürebilen donanımla işlemler arası iletişimi (IPC) engelleme gerektirir. Bu nedenle, CameraX bu API'leri yalnızca arka plan iş parçacıklarından çağırır. Böylece ana iş parçacığı engellenmez ve kullanıcı arayüzü akıcı durumda kalır. CameraX bu arka plan iş parçacıklarını dahili olarak yönetir ve bu davranış şeffaf görünür. Ancak bazı uygulamalar sıkı iş parçacıkları kontrolü gerektirir. CameraXConfig, bir uygulamanın CameraXConfig.Builder.setCameraExecutor() ve CameraXConfig.Builder.setSchedulerHandler() üzerinden kullanılan arka plan iş parçacıklarını ayarlamasına olanak tanır.

Kamera Yürütücü

Kamera yürütücü, tüm dahili Camera platformu API çağrıları ve bu API'lerden gelen geri çağırmalar için kullanılır. CameraX, bu görevleri gerçekleştirmek için bir dahili Executor ayırır ve yönetir. Ancak uygulamanız iş parçacıkları üzerinde daha fazla denetim gerektiriyorsa CameraXConfig.Builder.setCameraExecutor() kullanın.

Planlayıcı İşleyici

Planlayıcı işleyici, dahili görevlerin kullanılamadığı durumlarda kamerayı açmayı yeniden denemek gibi sabit aralıklarla planlamak için kullanılır. Bu işleyici, işleri yürütmez ve yalnızca kamera yürütücüsüne gönderir. Bazı durumlarda, geri çağırmalar için Handler gerektiren eski API platformlarında da kullanılır. Böyle durumlarda, geri çağırmalar hâlâ yalnızca doğrudan kamera yürütücüsüne gönderilir. CameraX, bu görevleri gerçekleştirmek için dahili bir HandlerThread ayırır ve yönetir ancak bunu CameraXConfig.Builder.setSchedulerHandler() ile geçersiz kılabilirsiniz.

Günlük kaydı

CameraX günlük kaydı, üretim kodunuzda ayrıntılı iletilerden kaçınmak için iyi bir uygulama olduğundan, uygulamaların logcat mesajlarını filtrelemesine olanak tanır. CameraX, en ayrıntılıdan en ciddi olana kadar dört günlük kaydı düzeyini destekler:

  • Log.DEBUG (varsayılan)
  • Log.INFO
  • Log.WARN
  • Log.ERROR

Bu günlük düzeylerinin ayrıntılı açıklamaları için Android Günlüğü belgelerine bakın. Uygulamanız için uygun günlük kaydı seviyesini ayarlamak üzere CameraXConfig.Builder.setMinimumLoggingLevel(int) kullanın.

Otomatik seçim

CameraX, uygulamanızın çalıştığı cihaza özel işlevleri otomatik olarak sağlar. Örneğin, bir çözünürlük belirtmezseniz veya belirttiğiniz çözünürlük desteklenmiyorsa CameraX kullanılacak en iyi çözünürlüğü otomatik olarak belirler. Tüm bunlar kitaplık tarafından gerçekleştirilir. Böylece cihaza özel kod yazmanız gerekmez.

CameraX'in hedefi kamera oturumunu başarıyla başlatmaktır. Yani CameraX, cihazın kapasitesine bağlı olarak çözünürlük ve en boy oranından ödün verir. Uzlaşmanın nedeni şunlar olabilir:

  • Cihaz, istenen çözünürlüğü desteklemiyor.
  • Cihazda, doğru çalışması için belirli çözünürlükleri gerektiren eski cihazlar gibi uyumluluk sorunları vardır.
  • Bazı cihazlarda, belirli biçimler yalnızca belirli en boy oranlarında kullanılabilir.
  • Cihazın, JPEG veya video kodlaması için "en yakın mod16" tercihi vardır. Daha fazla bilgi için SCALER_STREAM_CONFIGURATION_MAP adresini inceleyin.

Oturumu CameraX oluşturup yönetse de, döndürülen resim boyutlarını her zaman kodunuzdaki kullanım alanı çıktısında kontrol edin ve uygun şekilde ayarlayın.

Döndürme

Varsayılan olarak, kamera dönüşü, kullanım alanı oluşturulurken varsayılan ekranın dönüşüyle eşleşecek şekilde ayarlanır. Bu varsayılan durumda CameraX, uygulamanın önizlemede görmeyi beklediğinizle eşleşmesini sağlamak için çıkışlar üretir. Kullanım alanı nesnelerini yapılandırırken mevcut ekran yönünü geçirerek veya oluşturulduktan sonra dinamik olarak değiştirerek, çoklu ekranlı cihazları desteklemek için döndürme değerini özel bir değerle değiştirebilirsiniz.

Uygulamanız, yapılandırma ayarlarını kullanarak hedef rotasyonu ayarlayabilir. Böylece yaşam döngüsü çalışır durumda olsa bile kullanım alanı API'lerindeki yöntemleri (ör. ImageAnalysis.setTargetRotation()) kullanarak rotasyon ayarlarını güncelleyebilir. Bunu, uygulama dikey moda kilitli olduğunda (ve dolayısıyla rotasyon sırasında yeniden yapılandırma gerçekleşmediğinde) kullanabilirsiniz, ancak fotoğraf veya analiz kullanım alanının cihazın geçerli dönüşünü bilmesi gerekir. Örneğin, yüzlerin yüz algılama için doğru yönlendirilmesini veya fotoğrafların yatay ya da dikey olarak ayarlanmasını sağlamak amacıyla rotasyon farkındalığı gerekebilir.

Yakalanan görüntülere ait veriler döndürme bilgileri olmadan saklanabilir. EXIF verileri döndürme bilgileri içerir. Böylece, galeri uygulamaları kaydedildikten sonra resmi doğru yönde gösterebilir.

Önizleme verilerini doğru yönde görüntülemek için Preview.PreviewOutput() meta veri çıkışını kullanarak dönüşüm oluşturabilirsiniz.

Aşağıdaki kod örneğinde, bir yön etkinliğinde döndürmenin nasıl ayarlanacağı gösterilmektedir:

Kotlin

override fun onCreate() {
    val imageCapture = ImageCapture.Builder().build()

    val orientationEventListener = object : OrientationEventListener(this as Context) {
        override fun onOrientationChanged(orientation : Int) {
            // Monitors orientation values to determine the target rotation value
            val rotation : Int = when (orientation) {
                in 45..134 -> Surface.ROTATION_270
                in 135..224 -> Surface.ROTATION_180
                in 225..314 -> Surface.ROTATION_90
                else -> Surface.ROTATION_0
            }

            imageCapture.targetRotation = rotation
        }
    }
    orientationEventListener.enable()
}

Java

@Override
public void onCreate() {
    ImageCapture imageCapture = new ImageCapture.Builder().build();

    OrientationEventListener orientationEventListener = new OrientationEventListener((Context)this) {
       @Override
       public void onOrientationChanged(int orientation) {
           int rotation;

           // Monitors orientation values to determine the target rotation value
           if (orientation >= 45 && orientation < 135) {
               rotation = Surface.ROTATION_270;
           } else if (orientation >= 135 && orientation < 225) {
               rotation = Surface.ROTATION_180;
           } else if (orientation >= 225 && orientation < 315) {
               rotation = Surface.ROTATION_90;
           } else {
               rotation = Surface.ROTATION_0;
           }

           imageCapture.setTargetRotation(rotation);
       }
    };

    orientationEventListener.enable();
}

Ayarlanan rotasyona göre, her kullanım alanı resim verilerini doğrudan döndürür veya döndürülmeyen resim verilerinin tüketicilerine rotasyon meta verileri sağlar.

  • Önizleme: Hedef çözünürlük rotasyonunun Preview.getTargetRotation() kullanılarak bilinmesi için meta veri çıkışı sağlanır.
  • ImageAnalysis: Görüntü arabellek koordinatlarının görüntüleme koordinatlarına göre bilinmesi için meta veri çıkışı sağlanır.
  • ImageCapture: Resim Exif meta verileri, arabellek veya hem arabellek hem de meta veriler, döndürme ayarına dikkat etmek için değiştirilir. Değiştirilen değer, HAL uygulamasına bağlıdır.

Dikdörtgen kırpma

Varsayılan olarak kırpma çerçevesi tam tampon genişliğidir. Bunu ViewPort ve UseCaseGroup ile özelleştirebilirsiniz. Kullanım alanlarını gruplayarak ve görüntü alanını ayarlayarak CameraX, gruptaki tüm kullanım alanlarının kırpma dikdörtgenlerinin kamera sensöründe aynı alanı işaret etmesini garanti eder.

Aşağıdaki kod snippet'i, bu iki sınıfın nasıl kullanılacağını gösterir:

Kotlin

val viewPort =  ViewPort.Builder(Rational(width, height), display.rotation).build()
val useCaseGroup = UseCaseGroup.Builder()
    .addUseCase(preview)
    .addUseCase(imageAnalysis)
    .addUseCase(imageCapture)
    .setViewPort(viewPort)
    .build()
cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, useCaseGroup)

Java

ViewPort viewPort = new ViewPort.Builder(
         new Rational(width, height),
         getDisplay().getRotation()).build();
UseCaseGroup useCaseGroup = new UseCaseGroup.Builder()
    .addUseCase(preview)
    .addUseCase(imageAnalysis)
    .addUseCase(imageCapture)
    .setViewPort(viewPort)
    .build();
cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, useCaseGroup);

ViewPort, son kullanıcılara görünen tampon alanını tanımlar. Ardından CameraX, görüntü alanının özelliklerine ve ekli kullanım alanlarına göre mümkün olan en büyük kırpma alanını hesaplar. WYSIWYG efekti elde etmek için genellikle görüntü alanını önizleme kullanım alanına göre yapılandırabilirsiniz. Görüntü alanını elde etmenin basit bir yolu PreviewView kullanmaktır.

Aşağıdaki kod snippet'leri ViewPort nesnesinin nasıl alınacağını gösterir:

Kotlin

val viewport = findViewById<PreviewView>(R.id.preview_view).viewPort

Java

ViewPort viewPort = ((PreviewView)findViewById(R.id.preview_view)).getViewPort();

Yukarıdaki örnekte, PreviewView ölçek türünün varsayılan FILL_CENTER olarak ayarlandığı varsayıldığında, uygulamanın ImageAnalysis ve ImageCapture kaynağından aldığı sonuç, son kullanıcının PreviewView öğesinde gördükleriyle eşleşir. Çıkış arabelleğine kırpma dikimi ve döndürme uygulandıktan sonra, tüm kullanım alanlarındaki resim aynıdır ancak farklı çözünürlüklere sahip olması muhtemeldir. Dönüşüm bilgilerinin nasıl uygulanacağı hakkında daha fazla bilgi için çıkışı dönüştürme bölümüne bakın.

Kamera seçimi

CameraX, uygulamanızın ihtiyaçlarına ve kullanım alanlarına en uygun kamera cihazını otomatik olarak seçer. Sizin için seçilenden farklı bir cihaz kullanmak isterseniz birkaç seçeneğiniz vardır:

Aşağıdaki kod örneğinde, cihaz seçimini etkilemek için nasıl CameraSelector oluşturulacağı gösterilmektedir:

Kotlin

fun selectExternalOrBestCamera(provider: ProcessCameraProvider):CameraSelector? {
   val cam2Infos = provider.availableCameraInfos.map {
       Camera2CameraInfo.from(it)
   }.sortedByDescending {
       // HARDWARE_LEVEL is Int type, with the order of:
       // LEGACY < LIMITED < FULL < LEVEL_3 < EXTERNAL
       it.getCameraCharacteristic(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
   }

   return when {
       cam2Infos.isNotEmpty() -> {
           CameraSelector.Builder()
               .addCameraFilter {
                   it.filter { camInfo ->
                       // cam2Infos[0] is either EXTERNAL or best built-in camera
                       val thisCamId = Camera2CameraInfo.from(camInfo).cameraId
                       thisCamId == cam2Infos[0].cameraId
                   }
               }.build()
       }
       else -> null
    }
}

// create a CameraSelector for the USB camera (or highest level internal camera)
val selector = selectExternalOrBestCamera(processCameraProvider)
processCameraProvider.bindToLifecycle(this, selector, preview, analysis)

Aynı anda birden fazla kamera seç

CameraX 1.3'ten başlayarak, aynı anda birden fazla kamera da seçebilirsiniz. Örneğin, ön ve arka kamerayı bağlayarak fotoğraf çekebilir veya aynı anda her iki açıdan video kaydedebilirsiniz.

Eşzamanlı Kamera özelliği kullanılırken cihaz, aynı anda farklı yüzdeki lenslere sahip iki kamerayı veya aynı anda iki arka kamerayı çalıştırabilir. Aşağıdaki kod bloğunda, bindToLifecycle çağrılırken iki kameranın nasıl ayarlanacağı ve döndürülen ConcurrentCamera nesnesinden her iki Kamera nesnesinin nasıl alınacağı gösterilmektedir.

Kotlin

// Build ConcurrentCameraConfig
val primary = ConcurrentCamera.SingleCameraConfig(
    primaryCameraSelector,
    useCaseGroup,
    lifecycleOwner
)

val secondary = ConcurrentCamera.SingleCameraConfig(
    secondaryCameraSelector,
    useCaseGroup,
    lifecycleOwner
)

val concurrentCamera = cameraProvider.bindToLifecycle(
    listOf(primary, secondary)
)

val primaryCamera = concurrentCamera.cameras[0]
val secondaryCamera = concurrentCamera.cameras[1]

Java

// Build ConcurrentCameraConfig
SingleCameraConfig primary = new SingleCameraConfig(
    primaryCameraSelector,
    useCaseGroup,
    lifecycleOwner
);

SingleCameraConfig secondary = new SingleCameraConfig(
    primaryCameraSelector,
    useCaseGroup,
    lifecycleOwner
);

ConcurrentCamera concurrentCamera =  
    mCameraProvider.bindToLifecycle(Arrays.asList(primary, secondary));

Camera primaryCamera = concurrentCamera.getCameras().get(0);
Camera secondaryCamera = concurrentCamera.getCameras().get(1);

Kamera çözünürlüğü

KameraX'in resim çözünürlüğünü; cihaz özellikleri, cihazın desteklenen donanım seviyesi, kullanım alanı ve sağlanan en boy oranının bir kombinasyonuna göre ayarlamasına izin verebilirsiniz. Alternatif olarak, bu yapılandırmayı destekleyen kullanım alanlarında belirli bir hedef çözünürlük veya belirli bir en boy oranı ayarlayabilirsiniz.

Otomatik çözünürlük

CameraX, cameraProcessProvider.bindToLifecycle() içinde belirtilen kullanım alanlarına göre en iyi çözünürlük ayarlarını otomatik olarak belirleyebilir. Mümkün olduğunda, tek bir bindToLifecycle() çağrısında tek bir oturumda eşzamanlı olarak çalışmak için gereken tüm kullanım alanlarını belirtin. CameraX, cihazın desteklenen donanım düzeyini dikkate alarak ve cihaza özgü sapmayı dikkate alarak (cihaz mevcut akış yapılandırmalarını aştığında veya karşılamadığında) kullanım alanları grubuna göre çözünürlükleri belirler. Amaç, uygulamanın çok çeşitli cihazlarda çalışmasını sağlarken cihaza özel kod yollarını en aza indirmektir.

Görüntü yakalama ve görüntü analizi kullanım alanları için varsayılan en boy oranı 4:3'tür.

Kullanım alanları, uygulamanın kullanıcı arayüzü tasarımına göre istenen en boy oranını belirtmesi için yapılandırılabilir bir en boy oranına sahiptir. CameraX çıkışı, istenen en boy oranlarını cihazın desteklediği seviyeye uygun şekilde eşleşecek şekilde üretilir. Tam eşleşme çözümü desteklenmiyorsa en fazla koşulu karşılayan çözüm seçilir. Böylece, uygulama kameranın uygulamada nasıl görüneceğini belirler ve CameraX, farklı cihazlarda bunu karşılayacak en iyi kamera çözünürlüğü ayarlarını belirler.

Örneğin, bir uygulama aşağıdakilerden herhangi birini yapabilir:

  • Kullanım alanı için 4:3 veya 16:9 hedef çözünürlüğü belirtin
  • CameraX'in en yakın eşleşmeyi bulmaya çalıştığı özel bir çözünürlük belirtme
  • ImageCapture için kırpma en boy oranı belirtin

CameraX, dahili Camera2 yüzey çözünürlüklerini otomatik olarak seçer. Aşağıdaki tabloda çözünürlükler gösterilmektedir:

Kullanım alanı Dahili yüzey çözünürlüğü Çıkış verisi çözünürlüğü
Önizleme En Boy Oranı: Ayara en iyi uyan çözünürlük. Dahili yüzey çözünürlüğü. Görünüm'ün hedef en boy oranına göre kırpma, ölçeklendirme ve döndürme işlemi yapması için meta veriler sağlanır.
Varsayılan çözünürlük: Önizlemenin en boy oranıyla eşleşen en yüksek önizleme çözünürlüğü veya cihaz tarafından tercih edilen en yüksek çözünürlük.
Maksimum çözünürlük: Önizleme boyutu. Bu boyut, cihazın ekran çözünürlüğü ile en iyi eşleşmeyi veya 1080p (1920x1080) çözünürlüğünü (hangisi daha küçükse) ifade eder.
Görüntü analizi En boy oranı: Ayara en iyi sığan çözünürlük. Dahili yüzey çözünürlüğü.
Varsayılan çözünürlük: Varsayılan hedef çözünürlük ayarı 640x480'dir. Hem hedef çözünürlüğün hem de karşılık gelen en boy oranının ayarlanması, en iyi desteklenen çözünürlüğün elde edilmesini sağlar.
Maksimum çözünürlük: StreamConfigurationMap.getOutputSizes() adresinden alınan, kamera cihazının YUV_420_888 biçimindeki maksimum çıkış çözünürlüğü. Hedef çözünürlük varsayılan olarak 640x480 olarak ayarlanmıştır. Bu nedenle, 640x480'den büyük bir çözünürlük istiyorsanız desteklenen çözünürlüklerden en yakın olanı almak için setTargetResolution() ve setTargetAspectRatio() kullanmanız gerekir.
Görüntü yakalama En boy oranı: Ayara en uygun en boy oranı. Dahili yüzey çözünürlüğü.
Varsayılan çözünürlük: Mevcut en yüksek çözünürlük veya ImageCapture'ın en boy oranıyla eşleşen cihaz tarafından tercih edilen en yüksek çözünürlük.
Maksimum çözünürlük: Kamera cihazının JPEG biçimindeki maksimum çıkış çözünürlüğü. Bunu almak için StreamConfigurationMap.getOutputSizes() kullanın.

Çözünürlük belirtme

Kullanım alanları oluştururken, aşağıdaki kod örneğinde gösterildiği gibi setTargetResolution(Size resolution) yöntemini kullanarak belirli çözünürlükler ayarlayabilirsiniz:

Kotlin

val imageAnalysis = ImageAnalysis.Builder()
    .setTargetResolution(Size(1280, 720))
    .build()

Java

ImageAnalysis imageAnalysis =
  new ImageAnalysis.Builder()
    .setTargetResolution(new Size(1280, 720))
    .build();

Aynı kullanım alanında hem hedef en boy oranını hem de hedef çözünürlüğü ayarlayamazsınız. Bu işlem, yapılandırma nesnesi oluşturulurken bir IllegalArgumentException hatası verir.

Desteklenen boyutları hedef rotasyona göre döndürdükten sonra, çözünürlüğü Size koordinat çerçevesinde ifade edin. Örneğin, dikey resim isteyen ve doğal hedef rotasyonunda dikey doğal yöne sahip bir cihaz 480x640 boyutunda belirtebilir. Aynı cihazda, 90 derece döndürülmüş ve yatay yönü hedefleyen aynı cihaz 640x480 boyutunu belirtebilir.

Hedef çözünürlük, görüntü çözünürlüğü için minimum sınır oluşturmaya çalışır. Gerçek resim çözünürlüğü, kamera uygulaması tarafından belirlendiği şekilde, hedef çözünürlükten daha küçük olmayan, boyut olarak mevcut en yakın çözünürlükdür.

Bununla birlikte, hedef çözünürlüğe eşit veya bundan daha büyük bir çözünürlük yoksa hedef çözünürlükten daha küçük olan en yakın mevcut çözünürlük seçilir. Sağlanan Size ile aynı en boy oranına sahip çözünürlüklere, farklı en boy oranlarına sahip çözünürlüklerden daha yüksek öncelik verilir.

CameraX, isteklere göre en uygun çözünürlüğü uygular. Birincil ihtiyaç en boy oranını karşılamaksa yalnızca setTargetAspectRatio değerini belirtin. CameraX cihaza göre uygun olan belirli bir çözünürlüğü belirler. Uygulamanın birincil ihtiyacı, görüntü işlemeyi daha verimli hale getirmek için çözünürlük belirtmekse (örneğin, cihaz işleme özelliğine göre küçük veya orta boyutlu bir resim) setTargetResolution(Size resolution) özelliğini kullanın.

Uygulamanız tam çözünürlük gerektiriyorsa her donanım düzeyinin hangi maksimum çözünürlükleri desteklediğini belirlemek için createCaptureSession() içindeki tabloya bakın. Mevcut cihaz tarafından desteklenen belirli çözünürlükleri kontrol etmek için StreamConfigurationMap.getOutputSizes(int) sayfasını inceleyin.

Uygulamanız Android 10 veya sonraki bir sürümde çalışıyorsa belirli bir SessionConfiguration mülkünü doğrulamak için isSessionConfigurationSupported() aracını kullanabilirsiniz.

Kamera çıkışını kontrol et

CameraX, kamera çıkışını her kullanım alanında gerektiği şekilde yapılandırmanıza olanak tanımanın yanı sıra, tüm bağlantılı kullanım alanlarında yaygın olan kamera işlemlerini desteklemek için aşağıdaki arayüzleri de uygular:

  • CameraControl, genel kamera özelliklerini yapılandırmanıza olanak tanır.
  • CameraInfo, bu yaygın kamera özelliklerinin durumunu sorgulamanıza olanak tanır.

CameraControl ile desteklenen kamera özellikleri şunlardır:

  • Yakınlaştırma
  • Meşale
  • Odaklama ve Ölçüm (dokunmak için dokunma)
  • Pozlama Telafisi

CameraControl ve CameraInfo örneklerini alma

ProcessCameraProvider.bindToLifecycle() tarafından döndürülen Camera nesnesini kullanarak CameraControl ve CameraInfo örneklerini alın. Aşağıdaki kod bir örnek gösterir:

Kotlin

val camera = processCameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)

// For performing operations that affect all outputs.
val cameraControl = camera.cameraControl
// For querying information and states.
val cameraInfo = camera.cameraInfo

Java

Camera camera = processCameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)

// For performing operations that affect all outputs.
CameraControl cameraControl = camera.getCameraControl()
// For querying information and states.
CameraInfo cameraInfo = camera.getCameraInfo()

Örneğin, bindToLifecycle() çağırdıktan sonra yakınlaştırma ve diğer CameraControl işlemlerini gönderebilirsiniz. Kamera örneğini bağlamak için kullanılan etkinliği durdurduktan veya kaldırdığınızda CameraControl, artık işlemleri yürütemez ve başarısız bir ListenableFuture döndürür.

Yakınlaştırma

CameraControl, yakınlaştırma düzeyini değiştirmek için iki yöntem sunar:

  • setZoomRatio(), yakınlaştırma oranını yakınlaştırma oranına göre ayarlar.

    Oran, CameraInfo.getZoomState().getValue().getMinZoomRatio() ile CameraInfo.getZoomState().getValue().getMaxZoomRatio() aralığında olmalıdır. Aksi takdirde, işlev başarısız bir ListenableFuture döndürür.

  • setLinearZoom(), geçerli yakınlaştırmayı 0 ile 1,0 arasında doğrusal bir yakınlaştırma değeriyle ayarlar.

    Doğrusal yakınlaştırmanın avantajı, yakınlaştırmadaki değişikliklerle görüş alanının (FOV) ölçeklendirilmesidir. Bu nedenle, Slider görünümüyle kullanım için idealdir.

CameraInfo.getZoomState(), geçerli yakınlaştırma durumuna ait LiveData döndürür. Değer, kamera başlatıldığında veya yakınlaştırma düzeyi setZoomRatio() ya da setLinearZoom() kullanılarak ayarlandığında değişir. İki yöntemden herhangi birinin çağrılması, ZoomState.getZoomRatio() ve ZoomState.getLinearZoom() öğelerini destekleyen değerleri ayarlar. Bu, yakınlaştırma oranı metnini kaydırma çubuğunun yanında görüntülemek istediğinizde kullanışlıdır. Dönüşüm gerçekleştirmenize gerek kalmadan her ikisini de güncellemek için ZoomState LiveData gözlemlemesi yeterlidir.

Her iki API'nin döndürdüğü ListenableFuture, belirtilen yakınlaştırma değerine sahip yinelenen bir istek tamamlandığında uygulamalara bildirim gönderme seçeneği sunar. Buna ek olarak, önceki işlem devam ederken yeni bir yakınlaştırma değeri ayarlarsanız önceki yakınlaştırma işleminin ListenableFuture işlemi hemen başarısız olur.

Meşale

CameraControl.enableTorch(boolean), meşaleyi (el feneri olarak da bilinir) etkinleştirir veya devre dışı bırakır.

Mevcut lamba durumunu sorgulamak için CameraInfo.getTorchState() kullanılabilir. Flaşın kullanılabilir olup olmadığını belirlemek için CameraInfo.hasFlashUnit() tarafından döndürülen değeri kontrol edebilirsiniz. Aksi takdirde, CameraControl.enableTorch(boolean) çağrısı, döndürülen ListenableFuture öğesinin hemen başarısız bir sonuçla tamamlanmasına neden olur ve flaş durumunu TorchState.OFF olarak ayarlar.

Flaş etkinleştirildiğinde, fotoğraf ve video çekimi sırasında flashMode ayarından bağımsız olarak açık kalır. ImageCapture ürünündeki flashMode yalnızca flaş devre dışı bırakıldığında çalışır.

Odak ve Ölçme

CameraControl.startFocusAndMetering(), belirtilen FocusMeteringAction'a göre AF/AE/AWB ölçüm bölgelerini ayarlayarak otomatik odaklamayı ve pozlama sayacını tetikler. Bu genellikle birçok kamera uygulamasında "odaklamak için dokun" özelliğini uygulamak için kullanılır.

Ölçüm Noktası

Başlamak için MeteringPointFactory.createPoint(float x, float y, float size) kullanarak bir MeteringPoint oluşturun. MeteringPoint, kameradaki tek bir noktayı Surface temsil eder. AF/AE/AWB bölgelerini belirlemek üzere sensör koordinatlarına kolayca dönüştürülebilmesi için normalleştirilmiş bir biçimde saklanır.

MeteringPoint öğesinin boyutu 0 ile 1 arasında değişir ve varsayılan boyut 0, 15f'dir. MeteringPointFactory.createPoint(float x, float y, float size) çağrılırken CameraX, sağlanan size için merkezi (x, y) olan dikdörtgen bölge oluşturur.

MeteringPoint oluşturmak için aşağıdaki kodu kullanabilirsiniz:

Kotlin

// Use PreviewView.getMeteringPointFactory if PreviewView is used for preview.
previewView.setOnTouchListener((view, motionEvent) ->  {
val meteringPoint = previewView.meteringPointFactory
    .createPoint(motionEvent.x, motionEvent.y)
…
}

// Use DisplayOrientedMeteringPointFactory if SurfaceView / TextureView is used for
// preview. Please note that if the preview is scaled or cropped in the View,
// it’s the application's responsibility to transform the coordinates properly
// so that the width and height of this factory represents the full Preview FOV.
// And the (x,y) passed to create MeteringPoint might need to be adjusted with
// the offsets.
val meteringPointFactory = DisplayOrientedMeteringPointFactory(
     surfaceView.display,
     camera.cameraInfo,
     surfaceView.width,
     surfaceView.height
)

// Use SurfaceOrientedMeteringPointFactory if the point is specified in
// ImageAnalysis ImageProxy.
val meteringPointFactory = SurfaceOrientedMeteringPointFactory(
     imageWidth,
     imageHeight,
     imageAnalysis)

startFocusAndMetering ve FocusMeteringAction

startFocusAndMetering() yöntemini çağırmak için uygulamaların bir FocusMeteringAction derlemesi gerekir. Bu kuruluş, FLAG_AF, FLAG_AE ve FLAG_AWB kaynaklı isteğe bağlı sayaç modu kombinasyonlarıyla bir veya daha fazla MeteringPoints içerir. Aşağıdaki kod bu kullanımı gösterir:

Kotlin

val meteringPoint1 = meteringPointFactory.createPoint(x1, x1)
val meteringPoint2 = meteringPointFactory.createPoint(x2, y2)
val action = FocusMeteringAction.Builder(meteringPoint1) // default AF|AE|AWB
      // Optionally add meteringPoint2 for AF/AE.
      .addPoint(meteringPoint2, FLAG_AF | FLAG_AE)
      // The action is canceled in 3 seconds (if not set, default is 5s).
      .setAutoCancelDuration(3, TimeUnit.SECONDS)
      .build()

val result = cameraControl.startFocusAndMetering(action)
// Adds listener to the ListenableFuture if you need to know the focusMetering result.
result.addListener({
   // result.get().isFocusSuccessful returns if the auto focus is successful or not.
}, ContextCompat.getMainExecutor(this)

Önceki kodda gösterildiği gibi startFocusAndMetering(), yalnızca AF/AE/AWB sayaç bölgeleri için bir MeteringPoint ve yalnızca AF ve AE için başka bir MeteringPoint'ten oluşan FocusMeteringAction alır.

CameraX, dahili olarak bunu Camera2'ye MeteringRectangles dönüştürür ve yakalama isteğine karşılık gelen CONTROL_AF_REGIONS / CONTROL_AE_REGIONS / CONTROL_AWB_REGIONS parametrelerini ayarlar.

Her cihaz AF/AE/AWB ve birden çok bölgeyi desteklemediğinden CameraX FocusMeteringAction işlemini en iyi şekilde yürütür. CameraX, noktaların eklendiği sırayla, desteklenen maksimum MeteringPoint sayısını kullanır. Maksimum sayıdan sonra eklenen tüm ölçüm noktaları yoksayılır. Örneğin, bir FocusMeteringAction yalnızca 2'yi destekleyen bir platformda 3 MeteringPoint ile sağlanırsa sadece ilk 2 MeteringPoint kullanılır. Son MeteringPoint, CameraX tarafından yok sayılır.

Pozlama Telafisi

Pozlama telafisi, uygulamaların otomatik pozlama (AE) çıkış sonucunun ötesinde pozlama değerlerine (EV) ince ayar yapması gerektiğinde faydalıdır. Pozlama telafisi değerleri, geçerli resim koşulları için gerekli pozlamayı belirlemek üzere aşağıdaki şekilde birleştirilir:

Exposure = ExposureCompensationIndex * ExposureCompensationStep

CameraX, pozlama telafisini dizin değeri olarak ayarlamak için Camera.CameraControl.setExposureCompensationIndex() işlevini sağlar.

Pozitif dizin değerleri resmi daha parlak hale getirirken negatif değerler resmi karartır. Uygulamalar, bir sonraki bölümde açıklanan CameraInfo.ExposureState.exposureCompensationRange() aracılığıyla desteklenen aralığı sorgulayabilir. Değer destekleniyorsa döndürülen ListenableFuture, değer yakalama isteğinde başarıyla etkinleştirildiğinde tamamlanır. Belirtilen dizin desteklenen aralığın dışındaysa setExposureCompensationIndex() döndürülen ListenableFuture öğesinin hemen başarısız bir sonuçla tamamlanmasına neden olur.

CameraX yalnızca bekleyen en son setExposureCompensationIndex() isteğini tutar ve önceki istek yürütülmeden önce işlevi birden çok kez çağırmak işlemin iptal edilmesine neden olur.

Aşağıdaki snippet bir karşılaşma telafi dizini ayarlar ve pozlama değişikliği isteği yürütüldüğünde bir geri çağırma kaydeder:

Kotlin

camera.cameraControl.setExposureCompensationIndex(exposureCompensationIndex)
   .addListener({
      // Get the current exposure compensation index, it might be
      // different from the asked value in case this request was
      // canceled by a newer setting request.
      val currentExposureIndex = camera.cameraInfo.exposureState.exposureCompensationIndex
      …
   }, mainExecutor)
  • Camera.CameraInfo.getExposureState(), aşağıdakiler dahil olmak üzere geçerli ExposureState kodunu alır:

    • Maruz kalma telafisi kontrolünün desteklenebilirliği.
    • Geçerli pozlama telafi endeksi.
    • Pozlama telafi endeksi aralığı.
    • Pozlama telafi değeri hesaplamasında kullanılan pozlama telafisi adımı.

Örneğin, aşağıdaki kod geçerli ExposureState değerleriyle bir karşılaşma SeekBar ayarlarını başlatır:

Kotlin

val exposureState = camera.cameraInfo.exposureState
binding.seekBar.apply {
   isEnabled = exposureState.isExposureCompensationSupported
   max = exposureState.exposureCompensationRange.upper
   min = exposureState.exposureCompensationRange.lower
   progress = exposureState.exposureCompensationIndex
}

Ek kaynaklar

CameraX hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara bakın.

Kod laboratuvarı

  • CameraX'i Kullanmaya Başlama
  • Kod örneği

  • CameraX örnek uygulamaları
  • Geliştirici topluluğu

    Android CameraX Tartışma Grubu