Her bir CameraX kullanım alanını, kullanım alanının işlemlerinin farklı yönlerini kontrol edecek şekilde yapılandırırsınız.
Örneğin, Resim 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'leri kullanıma sunar. Kullanım alanlarına özel yapılandırma hakkında bilgi edinmek için Önizleme uygulama, Resimleri analiz etme ve Resim yakalama başlıklı makaleleri inceleyin.
CameraXConfig
CameraX, basitlik açısından ç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ştirmek istiyorsanız CameraXConfig arayüzünü kullanabilirsiniz.
CameraXConfig ile bir uygulama şunları yapabilir:
setAvailableCameraLimiter()ile başlangıç gecikmesini optimize edin.- Uygulamanın yürütücüsünü
setCameraExecutor()ile CameraX'e sağlayın. - Varsayılan programlayıcı işleyiciyi
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 aracının nasıl kullanılacağı açıklanmaktadır:
- Özelleştirilmiş yapılandırmalarınızla bir
CameraXConfignesnesi oluşturun. ApplicationiçindeCameraXConfig.Providerarayüzünü uygulayın vegetCameraXConfig()içindeCameraXConfignesnenizi döndürün.- Burada açıklandığı şekilde
ApplicationsınıfınızıAndroidManifest.xmldosyanıza ekleyin.
Örneğin, aşağıdaki kod örneği CameraX günlük kaydını yalnızca hata mesajlarıyla sınırlandırı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, cihazdaki kameraların özelliklerini listeler ve sorgular. CameraX'in donanım bileşenleriyle iletişim kurması gerektiğinden bu işlem, özellikle düşük kaliteli cihazlarda her kamera için önemli miktarda zaman alabilir. Uygulamanız cihazda yalnızca varsayılan ön kamera gibi belirli kameraları kullanıyorsa CameraX'i diğer kameraları yoksayacak şekilde ayarlayabilirsiniz. Bu sayede, uygulamanızın kullandığı kameraların başlatma gecikmesi azaltılabilir.
CameraXConfig.Builder.setAvailableCamerasLimiter() yöntemine iletilen CameraSelector bir kamerayı filtrelerse CameraX, o 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ırlandırır:
Kotlin
class MainApplication : Application(), CameraXConfig.Provider { override fun getCameraXConfig(): CameraXConfig { return CameraXConfig.Builder.fromConfig(Camera2Config.defaultConfig()) .setAvailableCamerasLimiter(CameraSelector.DEFAULT_BACK_CAMERA) .build() } }
İleti Dizileri
CameraX'in üzerine inşa edildiği platform API'lerinin çoğu, donanımla işlemler arası iletişimin (IPC) engellenmesini gerektirir. Bu işlem bazen yüzlerce milisaniye sürebilir. 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ı kalı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() aracılığıyla 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ı ve bu API'lerden gelen geri çağırmalar için kullanılır. CameraX, bu görevleri gerçekleştirmek için dahili bir Executor ayırır ve yönetir.
Ancak uygulamanız ileti dizileri üzerinde daha sıkı kontrol gerektiriyorsa CameraXConfig.Builder.setCameraExecutor() kullanın.
Zamanlayıcı İşleyici
Zamanlayıcı işleyici, dahili görevleri sabit aralıklarla planlamak için kullanılır.
Örneğin, kamera kullanılamadığında kamerayı açmayı yeniden denemek için kullanılabilir. Bu işleyici, işleri yürütmez ve yalnızca kamera yürütücüsüne gönderir. Ayrıca bazen geri çağırmalar için Handler gerektiren eski API platformlarında da kullanılır. Bu durumlarda geri çağırmalar 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 kodunuzda ayrıntılı mesajlardan kaçınmak için iyi bir yöntem olabilir. CameraX, en ayrıntılıdan en ciddi düzeye kadar dört günlük kaydı düzeyini destekler:
Log.DEBUG(varsayılan)Log.INFOLog.WARNLog.ERROR
Bu günlük düzeylerinin ayrıntılı açıklamaları için Android Günlük belgelerine 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 çalıştığı cihaza özel işlevleri otomatik olarak sağlar. Örneğin, CameraX, bir çözünürlük belirtmezseniz veya belirttiğiniz çözünürlük desteklenmiyorsa 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ıza gerek kalmaz.
CameraX'in amacı, kamera oturumunu başarıyla başlatmaktır. Yani CameraX, cihazın özelliklerine göre çözünürlük ve en boy oranlarından ödün verir. Güvenlik ihlali aşağıdaki nedenlerle gerçekleşebilir:
- Cihaz, istenen çözünürlüğü desteklemiyor.
- Cihazda uyumluluk sorunları varsa (ör. düzgün çalışması için belirli çözünürlükler gerektiren eski cihazlar)
- Bazı cihazlarda belirli biçimler yalnızca belirli en boy oranlarında kullanılabilir.
- Cihaz, JPEG veya video kodlama için "en yakın mod16" tercihine sahiptir. Daha fazla bilgi için
SCALER_STREAM_CONFIGURATION_MAPkonusuna 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
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ğinizle eşleşmesini sağlayacak çı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 dönüşü özel bir değere değiştirebilirsiniz.
Uygulamanız, yapılandırma ayarlarını kullanarak hedef dönüşü ayarlayabilir. Ardından, yaşam döngüsü çalışır durumdayken bile kullanım alanı API'lerindeki yöntemleri (ör. ImageAnalysis.setTargetRotation()) kullanarak rotasyon ayarlarını güncelleyebilir. Uygulama portre moduna kilitliyken ve bu nedenle döndürme sırasında yeniden yapılandırma gerçekleşmediğinde, ancak fotoğraf veya analiz kullanım alanının cihazın mevcut dönüşünden haberdar olması gerektiğinde bunu kullanabilirsiniz. Örneğin, yüz algılama için yüzlerin doğru şekilde yönlendirilmesi veya fotoğrafların yatay ya da dikey olarak ayarlanması için dönüş algılama gerekebilir.
Çekilen resimlerin verileri, döndürme bilgileri olmadan depolanabilir. 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önlendirmeyle görüntülemek için Preview.PreviewOutput() tarafından sağlanan meta veri çıkışını kullanarak dönüşümler oluşturabilirsiniz.
Aşağıdaki kod örneğinde, bir yönlendirme etkinliğinde dönüşün 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ı, resim verilerini 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önüşünün
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: Görüntünün Exif meta verileri, arabelleği veya hem arabelleği hem de meta verileri, döndürme ayarını belirtecek şekilde 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. ViewPort ve UseCaseGroup ile özelleştirebilirsiniz. CameraX, kullanım alanlarını gruplandırıp görüntü alanını ayarlayarak 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österilen tampon dikdörtgeni tanımlar. Ardından CameraX, görüntü alanının ve ekli kullanım alanlarının özelliklerine 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'lerinde 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();
Yukarıdaki örnekte, uygulamanın ImageAnalysis ve ImageCapture öğelerinden aldığı değerler, son kullanıcının PreviewView öğesinde gördüğü değerlerle eşleşir. Bu örnekte, PreviewView öğesinin ölçek türünün varsayılan değer olan FILL_CENTER olarak ayarlandığı varsayılmıştır. Kırpma dikdörtgeni ve döndürme, çıkış arabelleğine uygulandıktan sonra tüm kullanım alanlarındaki görüntü aynıdır ancak farklı çözünürlüklerde olabilir. Dönüşüm bilgilerinin nasıl uygulanacağı hakkında daha fazla bilgi için dönüşüm çıkışı bölümüne bakın.
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:
CameraSelector.DEFAULT_FRONT_CAMERAile varsayılan ön kamerayı isteyin.CameraSelector.DEFAULT_BACK_CAMERAile varsayılan arka kamerayı isteyin.- Kullanılabilir cihazların listesini
CameraSelector.Builder.addCameraFilter()ileCameraCharacteristicsölçütüne 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çme
CameraX 1.3'ten itibaren aynı anda birden fazla kamera da seçebilirsiniz. Örneğin, aynı anda her iki perspektiften fotoğraf çekmek veya video kaydetmek için ön ve arka kameraya bağlanabilirsiniz.
Eşzamanlı Kamera özelliğini kullanırken cihaz, farklı yönlere bakan lenslere sahip iki kamerayı 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 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üğü
CameraX'in görüntü çözünürlüğünü cihaz özelliklerinin, cihazın desteklediği donanım seviyesinin, kullanım alanının ve sağlanan en boy oranının bir kombinasyonuna göre ayarlamasını seçebilirsiniz. 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 oturumda eşzamanlı olarak çalıştırılması gereken tüm kullanım alanlarını tek bir bindToLifecycle() çağrısında belirtin. CameraX, çözünürlükleri cihazın desteklenen donanım seviyesini dikkate alarak ve cihaza özgü farklılıkları (cihazın mevcut akış yapılandırmalarını aştığı veya karşılamadığı durumlar) hesaba katarak bağlı kullanım alanları grubuna göre belirler.
Amaç, cihaza özgü kod yollarını en aza indirirken uygulamanın çok çeşitli cihazlarda çalışmasını sağlamaktır.
Resim 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ı belirtebilmesi için yapılandırılabilir bir en boy oranına sahiptir. CameraX çıkışı, istenen en boy oranlarıyla cihazın desteklediği ölçüde eşleşecek şekilde üretilir. Tam eşleşen bir çözünürlük desteklenmiyorsa en fazla koşulu karşılayan çözünürlük seçilir. Bu nedenle, uygulamanın kameranın uygulamada nasıl görüneceğini belirlemesi gerekir. CameraX ise farklı cihazlarda bu gereksinimi karşılayacak 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 belirtme
- CameraX'in en yakın eşleşmeyi bulmaya çalıştığı özel bir çözünürlük belirtin.
ImageCaptureiç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ümler gösterilmektedir:
| Kullanım alanı | Dahili yüzey çözünürlüğü | Çıkış verisi çözünürlüğü |
|---|---|---|
| Önizle | En Boy Oranı: Hedefi ayara en iyi şekilde uyduran çözünürlük. | Dahili yüzey çözünürlüğü. Meta veriler, bir görünümün hedef en boy oranı için kırpılması, ölçeklendirilmesi ve döndürülmesi amacıyla 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 tarafından tercih edilen en yüksek çözünürlük. | ||
| Maksimum çözünürlük: Cihazın ekran çözünürlüğüyle en iyi eşleşen boyut veya 1080p (1920x1080) (hangisi daha küçükse) olan önizleme boyutu. | ||
| Görüntü analizi | En boy oranı: Hedefi ayara en iyi şekilde uyduran çö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üğü hem de ilgili en boy oranını ayarlamak, en iyi desteklenen çözünürlüğü sağlar. | ||
Maksimum çözünürlük: Kamera cihazının, StreamConfigurationMap.getOutputSizes() adresinden alınan YUV_420_888 biçimindeki maksimum çıkış çözünürlüğü.
Hedef çözünürlük varsayılan olarak 640x480 şeklinde ayarlanır. Bu nedenle, 640x480'den daha yüksek 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.
|
||
| Resim 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
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. Bunu yaptığınızda, yapılandırma nesnesi oluşturulurken IllegalArgumentException hatası verilir.
Desteklenen boyutları hedef dönüşe göre döndürdükten sonra çözünürlüğü Size koordinat çerçevesinde ifade edin. Örneğin, doğal hedef rotasyonunda doğal dikey yönlendirmeye sahip bir cihaz, dikey resim isterken 480x640 değerini belirtebilir. Aynı cihaz, 90 derece döndürülüp yatay yönlendirmeyi hedeflediğinde 640x480 değerini belirtebilir.
Hedef çözünürlük, resim çözünürlüğü için minimum bir sınır belirlemeye çalışır. Gerçek görüntü çözünürlüğü, kamera uygulaması tarafından belirlenen hedef çözünürlükten küçük olmayan, boyuta en yakın çözünürlüktür.
Ancak hedef çözünürlüğe eşit veya hedef çözünürlükten 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üklerden daha yüksek öncelik verilir.
CameraX, isteklere göre en uygun çözünürlüğü uygular. Öncelikli ihtiyaç en boy oranını karşılamaksa yalnızca setTargetAspectRatio değerini belirtin. CameraX, cihaza göre uygun bir çözünürlük belirler.
Uygulamanın birincil ihtiyacı, görüntü işlemeyi daha verimli hale getirmek için bir çözünürlük belirtmekse (ör. cihazın işleme kapasitesine göre küçük veya orta boyutlu bir resim) setTargetResolution(Size resolution) kullanın.
Uygulamanız tam bir çözünürlük gerektiriyorsa her donanım seviyesinin desteklediği maksimum çözünürlükleri belirlemek için createCaptureSession() bölümündeki tabloya bakın. Mevcut cihazın desteklediği çö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 doğrulamak için isSessionConfigurationSupported() kullanabilirsiniz.
Kamera çıkışını kontrol etme
CameraX, kamera çıkışını her bir kullanım alanı için gerektiği gibi yapılandırmanıza olanak tanımanın yanı sıra, bağlı tüm 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:
- Zoom
- Torch
- Odaklama ve Ölçüm (dokunarak odaklama)
- 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() yöntemini ç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.
Zoom
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()ileCameraInfo.getZoomState().getValue().getMaxZoomRatio()arasında olmalıdır. Aksi takdirde işlev, başarısız birListenableFuturedöndürür.setLinearZoom(), mevcut yakınlaştırmayı 0 ile 1,0 arasında değişen doğrusal bir yakınlaştırma değeriyle ayarlar.Doğrusal yakınlaştırmanın avantajı, görüş alanının (FOV) yakınlaştırmadaki değişikliklerle ölçeklenmesini sağlamasıdır. Bu nedenle,
Slidergörünümüyle kullanım için idealdir.
CameraInfo.getZoomState()
mevcut yakınlaştırma durumunun LiveData'sını döndürür. Kamera başlatıldığında veya yakınlaştırma seviyesi setZoomRatio() ya da setLinearZoom() kullanılarak ayarlandığında değer 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ı metnini göstermek istiyorsanız kullanışlıdır.
Dönüştürme işlemi yapmadan her ikisini de güncellemek için ZoomState LiveData gözlemlemeniz yeterlidir.
Her iki API tarafından döndürülen ListenableFuture, belirtilen yakınlaştırma değerine sahip yinelenen bir istek tamamlandığında uygulamaların bildirim almasını sağlar. Ayrıca, önceki işlem devam ederken yeni bir yakınlaştırma değeri ayarlarsanız önceki yakınlaştırma işleminin ListenableFuture değeri hemen başarısız olur.
Torch
CameraControl.enableTorch(boolean)
el fenerini etkinleştirir veya devre dışı bırakır.
CameraInfo.getTorchState()
mevcut fener 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 değerinin başarısız sonuçla hemen tamamlanmasına neden olur ve el feneri durumunu TorchState.OFF olarak ayarlar.
Fener etkinleştirildiğinde, flashMode ayarından bağımsız olarak fotoğraf ve video çekimi sırasında açık kalır. ImageCapture uygulamasındaki flashMode, yalnızca fener devre dışı bırakıldığında çalışır.
Odak ve Ölçüm
CameraControl.startFocusAndMetering(),
verilen FocusMeteringAction'a göre AF/AE/AWB ölçüm bölgelerini ayarlayarak otomatik odaklama ve pozlama ölçümünü
tetikler. Bu yöntem genellikle birçok kamera uygulamasında "odaklamak için dokun" özelliğini uygulamak için kullanılır.
MeteringPoint
Başlamak için MeteringPointFactory.createPoint(float x, float y, float
size) kullanarak bir MeteringPoint oluşturun.
MeteringPoint, kameradaki tek bir noktayı temsil eder
Surface. AF/AE/AWB bölgelerini belirtmek için sensör koordinatlarına kolayca 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 dikdörtgen bir bölge oluşturur.
Aşağıdaki kodda MeteringPoint oluşturma işlemi 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() yöntemini çağırmak için uygulamaların bir FocusMeteringAction oluşturması gerekir. Bu nesne, FLAG_AF, FLAG_AE, FLAG_AWB arasından isteğe bağlı ölçüm modu kombinasyonları içeren bir veya daha fazla MeteringPoints öğesinden oluşur. Aşağıdaki kodda bu kullanım gösterilmektedir:
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)
Yukarıdaki kodda gösterildiği gibi,
startFocusAndMetering()
AF/AE/AWB ölçüm bölgeleri için bir MeteringPoint ve yalnızca AF ve 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.
Her cihaz AF/AE/AWB ve birden fazla bölgeyi desteklemediğinden CameraX, FocusMeteringAction işlemini en iyi şekilde yürütür. CameraX, desteklenen maksimum MeteringPoint sayısını, noktaların eklendiği sırayla kullanır. Maksimum sayıya ulaşıldıktan sonra eklenen tüm MeteringPoint'ler yok sayılır. Örneğin, yalnızca 2 MeteringPoint destekleyen bir platformda FocusMeteringAction için 3 MeteringPoint sağlanırsa yalnızca ilk 2 MeteringPoint kullanılır. Son MeteringPoint, CameraX tarafından yoksayılır.
Pozlama Telafisi
Pozlama telafisi, uygulamaların pozlama değerlerinde (EV) otomatik pozlama (AE) çıkış sonucunun ötesinde ince ayar yapması gerektiğinde kullanışlı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 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'nin başarısız sonuçla hemen tamamlanmasına neden olur.
CameraX yalnızca en son bekleyen setExposureCompensationIndex() isteğini saklar 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 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()mevcutExposureStatebilgilerini alır. Bu bilgiler şunlardır:- Pozlama telafisi kontrolünün desteklenebilirliği.
- Mevcut pozlama telafisi dizini.
- Pozlama telafisi dizini aralığı.
- Pozlama telafisi değeri hesaplamasında kullanılan pozlama telafisi adımı.
Örneğin, aşağıdaki kod, geçerli ExposureState değerleriyle bir pozlama SeekBar için ayarları 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 kaynakları inceleyin.
Codelab
Kod örneği
Geliştirici topluluğu
Android CameraX Tartışma Grubu