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:
setAvailableCameraLimiter()
ile başlatma gecikmesini optimize edin.- Uygulamanın yürütücüsünü CameraX'e
setCameraExecutor()
ile sağlayın. - Varsayılan planlayıcı işleyicisini
setSchedulerHandler()
ile değiştirin. - Günlük kaydı düzeyini
setMinimumLoggingLevel()
ile değiştirin.
Kullanım Modeli
Aşağıdaki prosedürde, CameraXConfig
ürününün nasıl kullanılacağı açıklanmaktadır:
- Özelleştirilmiş yapılandırmalarınızla bir
CameraXConfig
nesnesi oluşturun. CameraXConfig.Provider
arayüzünüApplication
içinde uygulayın veCameraXConfig
nesnenizigetCameraXConfig()
içinde döndürün.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:
CameraSelector.DEFAULT_FRONT_CAMERA
ile varsayılan ön kamerayı isteyin.CameraSelector.DEFAULT_BACK_CAMERA
ile varsayılan arka kamerayı isteyin.CameraSelector.Builder.addCameraFilter()
ile kullanılabilir cihazların listesiniCameraCharacteristics
özelliklerine göre filtreleyin.
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()
ileCameraInfo.getZoomState().getValue().getMaxZoomRatio()
aralığında olmalıdır. Aksi takdirde, işlev başarısız birListenableFuture
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çerliExposureState
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ı
Kod örneği
Geliştirici topluluğu
Android CameraX Tartışma Grubu