Yapılandırma seçenekleri

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

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

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 ayarları dinamik olarak değiştirmek için API'ler sunar. Tek tek 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 başlıklı makaleleri inceleyin.

CameraXConfig

CameraX, çoğu kullanım senaryosuna uygun 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 amaç için kullanılan arayüzdür.

CameraXConfig ile bir uygulama şunları yapabilir:

Kullanım modeli

Aşağıdaki prosedürde CameraXConfig simgesinin 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ğinde CameraX günlük kaydı yalnızca hata mesajlarıyla sınırlandırılmıştır:

Kotlin

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

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

Kamera Sınırlayıcı

ProcessCameraProvider.getInstance() ilk kez çağrıldığında CameraX, cihazda bulunan kameraların özelliklerini numaralandırır ve sorgular. CameraX'in donanım bileşenleriyle iletişim kurması gerektiğinden bu işlem, özellikle düşük seviye cihazlarda her kamera için önemli bir süre alabilir. Uygulamanız yalnızca cihazdaki belirli kameraları (ör. varsayılan ön kamera) kullanıyorsa CameraX'i diğer kameraları yoksayacak şekilde ayarlayabilirsiniz. Bu, uygulamanızın kullandığı kameraların başlatma gecikmesini azaltabilir.

CameraSelector, CameraXConfig.Builder.setAvailableCamerasLimiter()'a aktarıldığında bir kamerayı filtreliyorsa CameraX, söz konusu 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()
   }
}

Mesaj dizileri

CameraX'in temelini oluşturan platform API'lerinin çoğu, bazen yüzlerce milisaniye sürebilen donanımla engelleme işlemi gerektirir. Bu nedenle CameraX, ana iş parçacığının engellenmemesi ve kullanıcı arayüzünün akıcı kalması için bu API'leri yalnızca arka plan iş parçacıklarından çağırır. CameraX, bu arka plan iş parçacıklarını dahili olarak yönetir. Böylece bu davranış şeffaf görünür. Ancak bazı uygulamalar, iş parçacıklarının sıkı bir şekilde kontrol edilmesini 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.

Camera Executor

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

Scheduler Handler

Zamanlayıcı işleyici, dahili görevleri sabit aralıklarla planlamak için kullanılır. Örneğin, kamera kullanılamadığında açmayı yeniden deneme gibi. Bu işleyici, işleri yürütmez ve yalnızca kamera yürütücüsüne gönderir. Geri çağırmalar için Handler gerektiren eski API platformlarında da bazen kullanılır. Bu durumlarda geri çağırmalar yine 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ı, uygulamaların logcat mesajlarını filtrelemesine olanak tanır. Bu, üretim kodunuzdaki ayrıntılı mesajlardan kaçınmak için iyi bir uygulama olabilir. CameraX, en ayrıntılıdan en ciddiye 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üğü dokümanına bakın. Uygulamanız için uygun günlük kaydı düzeyini ayarlamak üzere CameraXConfig.Builder.setMinimumLoggingLevel(int) kullanın.

Otomatik seçim

CameraX, uygulamanızın üzerinde ç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 işlenir ve cihaza özel kod yazmanıza gerek kalmaz.

CameraX'in amacı, kamera oturumunu başarıyla başlatmaktır. Bu nedenle CameraX, cihazın özelliklerine göre çözünürlük ve en boy oranlarından ödün verir. Hesabın güvenliğinin ihlal edilmesinin nedenleri şunlar olabilir:

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

CameraX oturumu oluşturup yönetse de kodunuzdaki kullanım alanı çıkışında döndürülen resim boyutlarını her zaman kontrol edin ve buna göre ayarlayın.

Döndürme

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

Uygulamanız, yapılandırma ayarlarını kullanarak hedef döndürmeyi ayarlayabilir. Daha sonra, yaşam döngüsü çalışır durumdayken bile kullanım alanı API'lerindeki (ör. ImageAnalysis.setTargetRotation()) yöntemleri kullanarak döndürme ayarlarını güncelleyebilir. Bu işlevi, uygulama dikey moda kilitlendiğinde (böylece döndürme sırasında yeniden yapılandırma gerçekleşmez) ancak fotoğraf veya analiz kullanım alanının cihazın mevcut döndürme durumunun farkında olması gerektiğinde kullanabilirsiniz. Örneğin, yüzlerin yüz algılama için doğru şekilde yönlendirilmesi veya fotoğrafların yatay ya da dikey olarak ayarlanması için döndürme farkındalığı gerekebilir.

Çekilen resimlerin verileri, döndürme bilgisi olmadan saklanabilir. Exif verileri, galeri uygulamalarının resmi kaydettikten sonra doğru yönde gösterebilmesi için döndürme bilgilerini içerir.

Önizleme verilerini doğru yönde göstermek için Preview.PreviewOutput() çıkışından elde edilen meta verileri kullanarak dönüştürmeler oluşturabilirsiniz.

Aşağıdaki kod örneğinde, yönlendirme 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 bağlı olarak, her kullanım alanı resmi doğrudan döndürür veya döndürülmemiş resim verilerinin tüketicilerine rotasyon meta verileri sağlar.

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

Kırpma dikdörtgeni

Varsayılan olarak, kırpma dikdörtgeni tam arabellek dikdörtgenidir. Bu özelliği ViewPort ve UseCaseGroup ile özelleştirebilirsiniz. Kullanım alanlarını gruplandırıp 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 sağlar.

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

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 arabellek dikdörtgenini tanımlar. Ardından CameraX, görüntü alanının özelliklerine ve eklenen kullanım alanlarına göre mümkün olan en büyük kırpma dikdörtgenini hesaplar. Genellikle WYSIWYG efekti elde etmek için görüntü alanını önizleme kullanım alanına göre yapılandırabilirsiniz. Görüntü alanını almanın basit bir yolu PreviewView kullanmaktır.

Aşağıdaki kod snippet'inde ViewPort nesnesinin nasıl alınacağı gösterilmektedir:

Kotlin

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

Java

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

Önceki örnekte, ImageAnalysis ve ImageCapture uygulamasının elde ettiği bilgiler, PreviewView uygulamasının ölçek türünün varsayılan olarak FILL_CENTER ayarlandığı varsayıldığında, son kullanıcının PreviewView uygulamasında gördükleriyle eşleşir. Kırpma dikdörtgeni ve döndürme işlemi çıkış arabelleğine uygulandıktan sonra, tüm kullanım alanlarındaki görüntü aynı olur (çözünürlükleri farklı olabilir). Dönüşüm bilgilerini uygulama hakkında daha fazla bilgi için transform_output başlıklı makaleyi inceleyin.

Kamera seçimi

CameraX, uygulamanızın gereksinimleri ve kullanım alanları için en iyi kamera cihazını otomatik olarak seçer. Sizin için seçilen cihazdan farklı bir cihaz kullanmak istiyorsanız 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çme

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

Eşzamanlı Kamera özelliği kullanılırken cihaz, farklı yönlere bakan lenslere sahip iki kamerayı aynı anda çalıştırabilir veya iki arka kamerayı aynı anda ç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 Camera 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üğü

CameraX'in, cihaz özelliklerinin, cihazın desteklediği donanım düzeyinin, kullanım alanının ve sağlanan en boy oranının bir kombinasyonuna göre görüntü çözünürlüğünü 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üm

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 oturumda eşzamanlı olarak çalışması gereken tüm kullanım alanlarını tek bir bindToLifecycle() çağrısında belirtin. CameraX, cihazın desteklediği donanım düzeyini göz önünde bulundurarak ve cihaza özgü varyansı hesaba katarak (cihazın kullanılabilir akış yapılandırmalarını aştığı veya karşılamadığı durumlarda) çözünürlükleri belirler. Amaç, cihaza özel kod yollarını en aza indirirken uygulamanın çeşitli cihazlarda çalışmasını sağlamaktır.

Resim yakalama ve resim 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ı belirtmesine olanak tanıyan yapılandırılabilir bir en boy oranına sahiptir. CameraX çıkışı, cihazın desteklediği ölçüde istenen en-boy oranlarıyla eşleşecek şekilde üretilir. Tam eşleşme çözünürlüğü desteklenmiyorsa en çok koşulu karşılayan çözünürlük seçilir. Bu nedenle, uygulama kameranın uygulamada nasıl görüneceğini belirler ve CameraX, farklı cihazlarda bu gereksinimi karşılamak için en iyi kamera çözünürlüğü ayarlarını belirler.

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

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

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

Kullanım alanı Dahili yüzey çözünürlüğü Çıkış verisi çözünürlüğü
Önizle En-boy oranı: Hedefin ayara en uygun çözünürlüğü. Dahili yüzey çözünürlüğü. Görünümün hedef en boy oranına göre kırpılması, ölçeklendirilmesi ve döndürülmesi için meta veriler sağlanır.
Varsayılan çözünürlük: En yüksek önizleme çözünürlüğü veya önizlemenin en boy oranıyla eşleşen, cihazın tercih ettiği en yüksek çözünürlük.
Maksimum çözünürlük: Önizleme boyutu. Bu, cihazın ekran çözünürlüğüne veya 1080p'ye (1920x1080) en uygun boyutu ifade eder (hangisi daha küçükse).
Görüntü analizi En boy oranı: Hedefin ayara en uygun çözünürlüğü. 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 ilgili en boy oranının ayarlanması, en iyi desteklenen çözünürlükle sonuçlanır.
Maksimum çözünürlük: StreamConfigurationMap.getOutputSizes() cihazından alınan YUV_420_888 biçimindeki kamera cihazının maksimum çıkış çözünürlüğü. Hedef çözünürlük varsayılan olarak 640x480 olarak ayarlanır. Bu nedenle, 640x480'den daha büyük bir çözünürlük istiyorsanız desteklenen çözünürlükler arasından en yakın olanı elde etmek 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: Kullanılabilir en yüksek çözünürlük veya ImageCapture'ın en boy oranıyla eşleşen, cihazın tercih ettiği 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() kodunu kullanın.

Çözünürlük belirtme

Aşağıdaki kod örneğinde gösterildiği gibi, setTargetResolution(Size resolution) yöntemini kullanarak kullanım alanları oluştururken 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 durumda, yapılandırma nesnesi oluşturulurken IllegalArgumentException hatası verilir.

Desteklenen boyutlar hedef döndürme işlemine göre döndürüldükten sonra çözünürlüğü Size koordinat çerçevesinde ifade edin. Örneğin, doğal hedef rotasyonunda doğal yönü dikey olan ve dikey resim isteyen bir cihaz 480x640'ı belirtebilir. Aynı cihaz 90 derece döndürülüp yatay yönü hedeflediğinde ise 640x480'i belirtebilir.

Hedef çözünürlük, görüntü çözünürlüğü için minimum sınır oluşturmaya çalışır. Gerçek görüntü çözünürlüğü, Kamera uygulaması tarafından belirlenen hedef çözünürlükten daha küçük olmayan, boyutu en yakın olan çözünürlüktür.

Ancak hedef çözünürlüğe eşit veya daha büyük bir çözünürlük yoksa hedef çözünürlükten daha küçük olan en yakın çö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üklere göre daha yüksek öncelik verilir.

CameraX, isteklere göre en uygun çözünürlüğü uygular. Asıl amaç en boy oranını karşılamaksa yalnızca setTargetAspectRatio değerini belirtin. CameraX, cihaza uygun belirli bir çözünürlüğü belirler. Uygulamanın temel amacı, görüntü işlemeyi daha verimli hale getirmek için çözünürlük belirtmekse (ör. cihazın işleme kapasitesine göre küçük veya orta boyutlu bir görüntü) setTargetResolution(Size resolution) kullanın.

Uygulamanızın tam çözünürlük gerektirmesi durumunda, her donanım seviyesinin desteklediği maksimum çözünürlükleri belirlemek için createCaptureSession() bölümündeki tabloya bakın. Mevcut cihaz tarafından desteklenen belirli çözünürlükleri kontrol etmek için StreamConfigurationMap.getOutputSizes(int) bölümüne bakın.

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

Kamera çıkışını kontrol etme

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

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

CameraControl ile desteklenen kamera özellikleri şunlardır:

  • Yakınlaştır
  • Flaş
  • Odak ve ölçüm (odaklamak 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 kodda bir örnek gösterilmektedir:

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() işlevini ç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 yok ettikten sonra CameraControl artık işlem yürütemez ve başarısız bir ListenableFuture döndürür.

LifecycleOwner

Yakınlaştır

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

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

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

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

    Doğrusal yakınlaştırmanın avantajı, görüş alanının (FOV) yakınlaştırmadaki değişikliklere göre ölçeklenmesini sağlamasıdır. Bu nedenle, Slider görünümüyle kullanıma uygundur.

CameraInfo.getZoomState() geçerli yakınlaştırma durumunun LiveData'sını 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. Bu yöntemlerden birini çağırmak, ZoomState.getZoomRatio() ve ZoomState.getLinearZoom() değerlerini ayarlar. Bu, kaydırma çubuğunun yanında yakınlaştırma oranı metni göstermek istiyorsanız yararlı olur. Dönüşüm yapmanıza gerek kalmadan her ikisini de güncellemek için ZoomState LiveData simgesini gözlemlemeniz yeterlidir.

Her iki API tarafından döndürülen ListenableFuture, uygulamaların belirtilen yakınlaştırma değeriyle yinelenen bir istek tamamlandığında bildirim almasına olanak tanır. Ayrıca, önceki işlem yürütülmeye devam ederken yeni bir yakınlaştırma değeri ayarlarsanız önceki yakınlaştırma işlemi hemen ListenableFuture başarısız olur.

Flaş

CameraControl.enableTorch(boolean) El fenerini etkinleştirir veya devre dışı bırakır.

CameraInfo.getTorchState() meşalenin mevcut durumunu sorgulamak için kullanılabilir. Fenerin 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 başarısız sonuçla hemen tamamlanmasına ve el feneri durumunun TorchState.OFF olarak ayarlanmasına neden olur.

El feneri etkinleştirildiğinde, flashMode ayarından bağımsız olarak fotoğraf ve video çekimi sırasında açık kalır. ImageCapture içindeki flashMode yalnızca el feneri devre dışı bırakıldığında çalışır.

Odak ve Ölçüm

CameraControl.startFocusAndMetering() Belirtilen FocusMeteringAction'a göre AF/AE/AWB ölçüm bölgelerini ayarlayarak otomatik odaklamayı ve pozlama ölçümünü tetikler. Bu işlev, birçok kamera uygulamasında "odaklanmak için dokunma" özelliğini uygulamak için sıklıkla kullanılır.

MeteringPoint

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

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

Aşağıdaki kodda MeteringPoint nasıl oluşturulacağı gösterilmektedir:

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()'ı çağırmak için uygulamaların, FLAG_AF, FLAG_AE, FLAG_AWB'dan isteğe bağlı ölçüm modu kombinasyonlarıyla bir veya daha fazla MeteringPoints içeren bir FocusMeteringAction oluşturması gerekir. Aşağıdaki takip kodu 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() AF/AE/AWB ölçüm bölgeleri için bir MeteringPoint ve yalnızca AF ile AE için başka bir MeteringPoint'ten oluşan bir FocusMeteringAction alır.

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

AF/AE/AWB ve birden fazla bölge her cihazda desteklenmediğinden CameraX, FocusMeteringAction işlevini en iyi şekilde yürütür. CameraX, desteklenen maksimum sayıda MeteringPoint'i, noktaların eklendiği sırayla kullanır. Maksimum sayıdan sonra eklenen tüm ölçüm noktaları yoksayılır. Örneğin, yalnızca 2 Ölçüm Noktası'nı destekleyen bir platformda 3 Ölçüm Noktası ile bir FocusMeteringAction sağlanırsa yalnızca ilk 2 Ölçüm Noktası kullanılır. Son MeteringPoint, CameraX tarafından yok sayılır.

Pozlama Telafisi

Pozlama telafisi, uygulamaların pozlama değerlerini (EV) otomatik pozlama (AE) çıkış sonucunun ötesinde hassas bir şekilde ayarlaması gerektiğinde yararlıdır. Pozlama telafisi değerleri, mevcut görüntü koşulları için gerekli pozlamayı belirlemek üzere aşağıdaki şekilde birleştirilir:

Exposure = ExposureCompensationIndex * ExposureCompensationStep

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

Pozitif dizin değerleri görüntüyü daha parlak hale getirirken negatif değerler görüntüyü karartır. Uygulamalar, desteklenen aralığı bir sonraki bölümde açıklanan CameraInfo.ExposureState.exposureCompensationRange() ile 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'nın başarısız sonuçla hemen tamamlanmasına neden olur.

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

Aşağıdaki snippet, pozlama telafisi dizini ayarlar ve pozlama değişikliği isteği yürütüldüğünde 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() şunlar dahil olmak üzere mevcut ExposureState bilgilerini alır:

    • Pozlama telafisi kontrolünün desteklenebilirliği.
    • Mevcut pozlama telafisi endeksi.
    • Pozlama telafisi dizin aralığı.
    • Pozlama telafisi değeri hesaplamasında kullanılan pozlama telafisi adımı.

Örneğin, aşağıdaki kod, mevcut ExposureState değerleriyle bir gösterim 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 göz atın.

Codelab

  • CameraX'i kullanmaya başlama
  • Kod örneği

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

    Android CameraX Tartışma Grubu