Her 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 çekme kullanım örneğinde hedef en boy oranını ve flaş modunu 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();
Bazı kullanım alanları, yapılandırma seçeneklerine ek olarak API'leri kullanım alanı oluşturulduktan sonra ayarları dinamik olarak değiştirmek için gösterir. Kullanım alanlarına özgü yapılandırma hakkında bilgi edinmek için Önizleme uygulama, Resimleri analiz etme ve Resim yakalama başlıklı makaleleri inceleyin.
CameraXConfig
Basitlik sağlamak için CameraX, ç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 ediyorsanız CameraXConfig
bu amaç için kullanabileceğiniz arayüzdür.
CameraXConfig
ile bir uygulama şunları yapabilir:
setAvailableCameraLimiter()
ile başlatma gecikmesini optimize edin.- Uygulamanın yürütücüsünü
setCameraExecutor()
ile CameraX'e 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
değerinin nasıl kullanılacağı açıklanmaktadır:
- Özelleştirilmiş yapılandırmalarınızla bir
CameraXConfig
nesnesi oluşturun. Application
öğenizeCameraXConfig.Provider
arayüzünü uygulayın veCameraXConfig
nesnenizigetCameraXConfig()
içinde döndürün.- Burada açıklandığı gibi
Application
sınıfınızıAndroidManifest.xml
dosyanıza 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, ayarladı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 listeler ve sorgular. CameraX'in donanım bileşenleriyle iletişim kurması gerektiğinden bu işlem, özellikle de düşük kaliteli cihazlarda her kamera için önemli miktarda zaman 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.
CameraXConfig.Builder.setAvailableCamerasLimiter()
metoduna iletilen CameraSelector
bir kamerayı filtrelerse 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ı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() } }
Mesaj dizileri
CameraX'in oluşturulduğu platform API'lerinin çoğu, bazen yanıt vermesi yüzlerce milisaniye sürebilen donanımla işlemler arası iletişimi (IPC) engellemeyi gerektirir. Bu nedenle CameraX, ana iş parçacığının engellenmemesini ve kullanıcı arayüzünün akıcı kalmasını sağlamak için bu API'leri yalnızca arka plan iş parçacıklarından çağırır. CameraX, bu davranışın şeffaf görünmesi için bu arka plan iş parçacıklarını dahili olarak yönetir. Ancak bazı uygulamalarda mesaj dizilerinin sıkı bir şekilde kontrol edilmesi gerekir. 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.
Kamera Yürütücü
Kamera yürütücü, tüm dahili kamera platformu API çağrıları ve bu API'lerden gelen geri çağırma çağrıları 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 için daha sıkı bir iş parçacığı kontrolü gerekiyorsa CameraXConfig.Builder.setCameraExecutor()
değerini kullanın.
Planlayıcı işleyici
Planlayıcı işleyici, dahili görevleri sabit aralıklarla planlamak için kullanılır (ör. kamera kullanılamadığında kamerayı tekrar açmayı denemek). Bu işleyici, işleri yürütmez ve yalnızca kamera yürütücüye gönderir. Bazen geri çağırma için Handler
gerektiren eski API platformlarında da kullanılır. Bu gibi durumlarda geri çağırma işlevleri yine yalnızca doğrudan kamera yürütücüye 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 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üğü belgelerine bakın. Uygulamanız için uygun günlük kaydı düzeyini ayarlamak üzere CameraXConfig.Builder.setMinimumLoggingLevel(int)
değerini kullanın.
Otomatik seçim
CameraX, uygulamanızın çalıştığı cihaza özgü 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 bu işlemler kitaplık tarafından gerçekleştirilir. Böylece cihaza özel kod yazmak zorunda kalmazsınız.
CameraX'in amacı, kamera oturumunu başarıyla başlatmaktır. Bu, CameraX'in cihazın kapasitesine göre çözünürlük ve en boy oranlarında ödün vereceği anlamına gelir. Güvenlik ihlali aşağıdaki nedenlerden dolayı gerçekleşebilir:
- Cihaz, istenen çözünürlüğü desteklemiyor.
- Cihazın uyumluluk sorunları vardır (ö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 kodlaması için "en yakın mod16" tercihine sahiptir. 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
Kamera rotasyonu, kullanım alanı oluşturulurken varsayılan ekranın rotasyonuyla eşleşecek şekilde varsayılan olarak ayarlanır. Bu varsayılan durumda CameraX, uygulamanın önizlemede görmeyi beklediğinizle eşleşmesini sağlamak için çıkışlar oluşturur. Kullanım alanı nesnelerini yapılandırırken mevcut ekran yönünü ileterek veya oluşturulduktan sonra dinamik olarak çok ekranlı cihazları desteklemek için rotasyonu özel bir değerle değiştirebilirsiniz.
Uygulamanız, yapılandırma ayarlarını kullanarak hedef rotasyonu ayarlayabilir. Daha sonra, kullanım alanı API'lerindeki yöntemleri (ör. ImageAnalysis.setTargetRotation()
) kullanarak döngü ayarlarını yaşam döngüsü çalışır durumdayken bile güncelleyebilir. Bu yöntemi, uygulama dikey moda kilitlendiğinde (ve dolayısıyla döndürüldüğünde yeniden yapılandırma yapılmadığında) kullanabilirsiniz. Ancak fotoğraf veya analiz kullanım alanının, cihazın mevcut dönüşünü bilmesi gerekir. Örneğin, yüz algılama için yüzlerin doğru yönde olması veya fotoğrafların yatay ya da dikey olarak ayarlanması amacıyla döndürme farkındalığı gerekebilir.
Çekilen resimlere ait veriler, 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önde görüntülemek için dönüştürme işlemi oluşturmak üzere Preview.PreviewOutput()
kaynağından elde edilen meta verileri kullanabilirsiniz.
Aşağıdaki kod örneğinde, bir oryantasyon etkinliğindeki dönüşümü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(); }
Her kullanım alanı, ayarlanan rotasyona bağlı olarak görüntü verilerini doğrudan döndürür veya döndürülmemiş görüntü verilerinin tüketicilerine rotasyon meta verilerini sağlar.
- Önizleme: Meta veri çıkışı,
Preview.getTargetRotation()
kullanılarak hedef çözünürlüğün döndürülmesinin bilinmesi için sağlanır. - ImageAnalysis: Meta veri çıkışı, resim arabelleği koordinatlarının görüntü koordinatlarına göre bilinmesi için sağlanır.
- ImageCapture: Resmin Exif meta verileri, arabelleği veya hem arabellek 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
Kırpma dikdörtgeni varsayılan olarak 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ündeki aynı alanı işaretlemesini 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ıların görebileceği arabellek dikdörtgenini tanımlar. Ardından CameraX, görüntü alanının özelliklerine ve bağlı 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ı elde etmenin 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();
Önceki örnekte, uygulamanın ImageAnalysis
ve ImageCapture
'ten aldığı değerler, PreviewView
'nin ölçek türünün varsayılan FILL_CENTER
olarak ayarlandığı varsayılarak son kullanıcının PreviewView
'de gördüğü değerlerle 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 resim aynıdır ancak farklı çözünürlüklere sahip olabilir. Dönüşüm bilgilerinin nasıl uygulanacağı hakkında daha fazla bilgi için çıktıyı dönüştürme 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_CAMERA
ile varsayılan ön kamerayı isteyin.CameraSelector.DEFAULT_BACK_CAMERA
simgesini kullanarak varsayılan arka kamerayı isteyin.- Kullanılabilir cihazların listesini
CameraSelector.Builder.addCameraFilter()
ileCameraCharacteristics
özelliklerine göre filtreleyin.
Aşağıdaki kod örneğinde, cihaz seçimini etkilemek için CameraSelector
öğesinin nasıl 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)
Eşzamanlı olarak birden fazla kamera seçme
CameraX 1.3'ten itibaren aynı anda birden fazla kamera da seçebilirsiniz. Örneğin, ön ve arka kamerayı bağlayarak aynı anda her iki açıdan da fotoğraf çekebilir veya video kaydedebilirsiniz.
Eşzamanlı Kamera özelliği kullanıldığında 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 Camera nesnesinin de 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 özelliklerine, cihazın desteklediği donanım düzeyine, kullanım alanına ve sağlanan en boy oranına göre resim çö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ış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 düzeyini ve cihaza özgü varyasyonu (cihazın mevcut yayın yapılandırmalarını aştığı veya karşılamadığı durumlar) dikkate alarak bağlı kullanım alanı grubuna göre belirler.
Amaç, cihaza özel kod yollarını en aza indirirken uygulamanın çok ç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ışı, istenen en boy oranlarıyla cihazın desteklediği en yakın şekilde eşleşecek şekilde üretilir. Tam eşleşme çözümü desteklenmiyorsa en fazla koşulu karşılayan çözüm seçilir. Bu nedenle, kameranın uygulamada nasıl görüneceğini uygulama belirler ve CameraX, 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 belirtin
- CameraX'in en yakın eşleşmeyi bulmaya çalıştığı özel bir çözünürlük belirtin
ImageCapture
için kırpma en boy oranı belirtin
CameraX, dahili Camera2 yüzey çözünürlüğünü 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ı: Hedefe ayarlara en uygun çözünürlük. | Dahili yüzey çözünürlüğü. Meta veriler, bir Görünümün hedef en boy oranına göre kırpılmasına, ölçeklendirilmesine ve döndürülmesine olanak tanır. |
Varsayılan çözünürlük: En yüksek önizleme çözünürlüğü veya önizlemenin en boy oranına uyan, cihaz tarafından tercih edilen en yüksek çözünürlük. | ||
Maksimum çözünürlük: Cihazın ekran çözünürlüğüne veya 1080p'ye (1920x1080) en uygun boyutu ifade eden önizleme boyutu. | ||
Görüntü analizi | En boy oranı: Hedefe ayarlara en uygun çö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'tür. Hem hedef çözünürlüğü hem de ilgili en boy oranını ayarlamak, en iyi desteklenen çözünürlüğe yol açar. | ||
Maksimum çözünürlük: Kamera cihazının, StreamConfigurationMap.getOutputSizes() kaynağından alınan 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'ten daha büyük bir çözünürlük istiyorsanız desteklenen çözünürlüklerden en yakınını almak için setTargetResolution() ve setTargetAspectRatio() özelliklerini kullanmanız gerekir.
|
||
Resim yakalama | En boy oranı: Ayarlara 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ına uyan, 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üğü. Bu bilgiyi almak için StreamConfigurationMap.getOutputSizes() seçeneğini kullanın.
|
Çözünürlük belirtin
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 işlem, yapılandırma nesnesi oluşturulurken bir IllegalArgumentException
hatası oluşturur.
Desteklenen boyutları hedef rotasyona göre döndürdükten sonra çözünürlüğü Size
koordinat çerçevesinde ifade edin. Örneğin, doğal hedef rotasyonda dikey doğal yönü olan ve dikey resim isteyen bir cihaz 480x640'ü belirtebilir. Aynı cihaz, 90 derece döndürülmüş ve yatay yönü hedefleyen bir cihaz ise 640x480'ü belirtebilir.
Hedef çözünürlük, resim çözünürlüğü için minimum bir sınır belirlemeye çalışır. Gerçek resim çözünürlüğü, kamera uygulaması tarafından belirlenen hedef çözünürlükten küçük olmayan en yakın çözünürlüktür.
Ancak hedef çözünürlüğe eşit veya hedef çözünürlüğden daha büyük bir çözünürlük yoksa hedef çözünürlüğe en yakın, çözünürlüğü daha düşük çö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. Birincil 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 işleme kapasitesine göre küçük veya orta boyutlu bir resim) setTargetResolution(Size resolution)
değerini kullanın.
Uygulamanız için tam çözünürlük gerekiyorsa her donanım düzeyinde desteklenen 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()
'i 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:
- Yakınlaştırma
- Torch
- Odak ve ölçüm (odaklanmak 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()
çağrısından sonra yakınlaştırma ve diğer CameraControl
işlemlerini gönderebilirsiniz. Kamera örneğini bağlamak için kullanılan etkinliği durdurduğunuzda veya yok ettiğinizde CameraControl
artık işlem yapamaz 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ı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 birListenableFuture
döndürür.setLinearZoom()
, geçerli 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ı (FOV) yakınlaştırmadaki değişikliklerle ölçeklendirmektir. Bu,
Slider
gö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ılırken veya yakınlaştırma düzeyi setZoomRatio()
veya setLinearZoom()
kullanılarak ayarlandığında değer değişir. Bu yöntemlerden herhangi biri çağrıldığında ZoomState.getZoomRatio()
ve ZoomState.getLinearZoom()
için destekleyici değerler ayarlanır.
Bu, kaydırma çubuğunun yanında yakınlaştırma oranı metnini görüntülemek istiyorsanız yararlı olur.
Dönüşüm yapmanıza gerek kalmadan her ikisini de güncellemek için ZoomState
LiveData
değerini gözlemlemeniz yeterlidir.
Her iki API tarafından da döndürülen ListenableFuture
, belirtilen yakınlaştırma değerine sahip yinelenen bir istek tamamlandığında uygulamaların bilgilendirilmesini sağlar. Ayrıca, önceki işlem hâlâ yürütülürken yeni bir yakınlaştırma değeri ayarlarsanız önceki yakınlaştırma işleminin ListenableFuture
hemen başarısız olur.
Torch
CameraControl.enableTorch(boolean)
el fenerini (işaret ışığı olarak da bilinir) etkinleştirir veya devre dışı bırakır.
CameraInfo.getTorchState()
mevcut el feneri durumunu sorgulamak için kullanılabilir. El feneri 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
işlevinin hemen başarısız bir sonuçla tamamlanmasına neden olur ve el feneri durumunu TorchState.OFF
olarak ayarlar.
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
'daki flashMode
yalnızca el feneri devre dışıyken çalışır.
Odak ve Ölçüm
CameraControl.startFocusAndMetering()
, belirtilen FocusMeteringAction'a göre AF/AE/AWB ölçüm bölgelerini ayarlayarak otomatik odaklama ve pozlama ölçümünü tetikler. Bu yöntem, birçok kamera uygulamasında "odaklamak için dokun" ö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 bir MeteringPoint
oluşturun.
MeteringPoint
, kameradaki tek bir noktayı temsil ederSurface
. 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. CameraX, MeteringPointFactory.createPoint(float x, float y, float
size)
çağrılırken sağlanan size
için (x, y)
merkezli bir dikdörtgen bölge oluşturur.
Aşağıdaki kodda, MeteringPoint
öğesinin 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()
'u çağırmak için uygulamaların, FLAG_AF
, FLAG_AE
ve FLAG_AWB
'deki isteğe bağlı ölçüm modu kombinasyonlarıyla bir veya daha fazla MeteringPoints
içeren bir FocusMeteringAction
oluşturması gerekir. Aşağıdaki kod bu kullanımı göstermektedir:
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 ve AE için başka bir MeteringPoint içeren bir FocusMeteringAction
alır.
CameraX, bu isteği dahili olarak Camera2'ye dönüştürürMeteringRectangles
ve ilgili CONTROL_AF_REGIONS
/
CONTROL_AE_REGIONS
/
CONTROL_AWB_REGIONS
parametrelerini yakalama isteğine ayarlar.
Her cihaz AF/AE/AWB'yi ve birden fazla bölgeyi desteklemediğinden CameraX, FocusMeteringAction
işlevini en iyi şekilde yürütür. CameraX, desteklenen maksimum sayıda MeteringPoints değerini, noktaların eklenme sırasına göre kullanır. Maksimum sayıdan sonra eklenen tüm MeteringPoints yoksayılır. Örneğin, yalnızca 2'yi destekleyen bir platformda bir FocusMeteringAction
'e 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 otomatik pozlama (AE) çıkış sonucunun ötesinde pozlama değerlerinde (EV) 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 telaffuzunu dizin değeri olarak ayarlamak için Camera.CameraControl.setExposureCompensationIndex()
işlevini sağlar.
Pozitif dizin değerleri resmi parlaklaştırırken negatif değerler resmi 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 hemen başarısız bir sonuçla 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, bir pozlama telafisi dizini ayarlar ve pozlama değişikliği isteği yürütüldüğünde geri çağırma işlevi 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()
şu bilgileri içeren mevcutExposureState
değerini alır:- Pozlama telafisi kontrolünün desteklenebilirliği.
- Mevcut pozlama telafisi indeksi.
- Pozlama telafisi dizini aralığı.
- Pozlama telafisi değeri hesaplamasında kullanılan pozlama telafisi adımı.
Örneğin, aşağıdaki kod bir gösterim SeekBar
için ayarları mevcut ExposureState
değerleriyle 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
Kod örneği
Geliştirici topluluğu
Android CameraX Tartışma Grubu