Bu konuda, ImageAnalysis
veya ImageCapture
kullanım alanından doğru döndürme bilgileri içeren resimler almak için uygulamanızda CameraX kullanım alanlarını nasıl ayarlayacağınız gösterilmektedir. Bu nedenle:
ImageAnalysis
kullanım alanınınAnalyzer
doğru döndürülmüş kareler almalıdır.ImageCapture
kullanım alanı, fotoğrafları doğru döndürmeyle çekmelidir.
Terminoloji
Bu konuda aşağıdaki terminoloji kullanılır. Bu nedenle, her terimin ne anlama geldiğini bilmeniz önemlidir:
- Ekran yönü
- Cihazın hangi tarafının yukarı baktığını belirtir ve dört değerden biri olabilir: dikey, yatay, ters dikey veya ters yatay.
- Ekran döndürme
- Bu,
Display.getRotation()
tarafından döndürülen değerdir ve cihazın doğal yönüne göre saat yönünün tersine döndürüldüğü dereceleri temsil eder. - Hedef rotasyon
- Bu değer, cihazın doğal yönüne ulaşması için saat yönünde döndürülmesi gereken derece sayısını gösterir.
Hedef rotasyonu belirleme
Aşağıdaki örneklerde, bir cihazın doğal yönelimine göre hedef rotasyonunun nasıl belirleneceği gösterilmektedir.
1. örnek: Dikey doğal yön
Cihaz örneği: Pixel 3 XL | |
---|---|
Doğal yön = Dikey Ekran döndürme = 0 |
|
Doğal yön = Dikey Ekran döndürme = 90 |
2. Örnek: Yatay doğal yön
Cihaz örneği: Pixel C | |
---|---|
Doğal yön = Yatay Ekran döndürme = 0 |
|
Doğal yön = Yatay Ekran döndürme = 270 |
Resim döndürme
Hangi uç yukarı bakıyor? Sensör yönü, Android'de sabit bir değer olarak tanımlanır. Bu değer, cihaz doğal konumdayken sensörün cihazın üst kısmından döndürüldüğü dereceleri (0, 90, 180, 270) gösterir. Şemalardaki tüm durumlarda, resim döndürme, verilerin dikey görünmesi için saat yönünde nasıl döndürülmesi gerektiğini açıklar.
Aşağıdaki örneklerde, kamera sensörünün yönüne bağlı olarak görüntünün nasıl döndürülmesi gerektiği gösterilmektedir. Ayrıca, hedef rotasyonunun görüntü rotasyonuna ayarlandığı varsayılır.
Örnek 1: Sensör 90 derece döndürülmüş
Cihaz örneği: Pixel 3 XL | |
---|---|
Ekran döndürme = 0 |
|
Ekran döndürme = 90 |
2. örnek: Sensör 270 derece döndürülmüş
Cihaz örneği: Nexus 5X | |
---|---|
Ekran döndürme = 0 |
|
Ekran döndürme = 90 |
3. örnek: Sensör 0 derece döndürülmüş
Cihaz örneği: Pixel C (Tablet) | |
---|---|
Ekran döndürme = 0 |
|
Ekran döndürme = 270 |
Bir resmin döndürülmüşlüğünü hesaplama
ImageAnalysis
ImageAnalysis
'nin Analyzer
, kameradan ImageProxy
biçiminde resim alır. Her resimde, aşağıdakiler aracılığıyla erişilebilen döndürme bilgileri bulunur:
val rotation = imageProxy.imageInfo.rotationDegrees
Bu değer, resmin ImageAnalysis
'ün hedef rotasyonuyla eşleşmesi için saat yönünde döndürülmesi gereken dereceleri temsil eder. Bir Android uygulaması bağlamında, ImageAnalysis
'ün hedef rotasyonu genellikle ekranın yönüyle eşleşir.
ImageCapture
Bir yakalama sonucunun hazır olduğunu bildirmek için ImageCapture
örneğine geri çağırma işlevi eklenir. Sonuç, çekilen resim veya bir hata olabilir.
Fotoğraf çekilirken sağlanan geri çağırma aşağıdaki türlerden biri olabilir:
OnImageCapturedCallback
:ImageProxy
biçiminde bellek içi erişime sahip bir resim alır.OnImageSavedCallback
: Çekilen resimImageCapture.OutputFileOptions
tarafından belirtilen konumda başarıyla depolandığında çağrılır. Seçenekler,File
,OutputStream
veyaMediaStore
'deki bir yeri belirtebilir.
Formatından (ImageProxy
, File
, OutputStream
, MediaStore Uri
) bağımsız olarak çekilen görüntünün döndürülmesi, ImageCapture
'in hedef döndürmesiyle eşleşmesi için çekilen görüntünün saat yönünde döndürülmesi gereken döndürme derecelerini temsil eder. Bu döndürme derecesi, Android uygulaması bağlamında genellikle ekranın yönüyle eşleşir.
Çekilen görüntünün döndürülmesi aşağıdaki yöntemlerden biriyle alınabilir:
ImageProxy
val rotation = imageProxy.imageInfo.rotationDegrees
File
val exif = Exif.createFromFile(file) val rotation = exif.rotation
OutputStream
val byteArray = outputStream.toByteArray() val exif = Exif.createFromInputStream(ByteArrayInputStream(byteArray)) val rotation = exif.rotation
MediaStore uri
val inputStream = contentResolver.openInputStream(outputFileResults.savedUri) val exif = Exif.createFromInputStream(inputStream) val rotation = exif.rotation
Bir resmin döndürüldüğünü doğrulama
ImageAnalysis
ve ImageCapture
kullanım alanları, başarılı bir yakalama isteği sonrasında kameradan ImageProxy
alır. ImageProxy
, bir resmi ve döndürülmesi de dahil olmak üzere resimle ilgili bilgileri kapsar. Bu döndürme bilgileri, kullanım alanının hedef döndürmesiyle eşleşmesi için resmin döndürülmesi gereken dereceleri temsil eder.
ImageCapture/ImageAnalysis hedefi döndürme yönergeleri
Birçok cihaz varsayılan olarak dikey veya yatay modu tersine çevirmez. Bu nedenle, bazı Android uygulamaları bu yönleri desteklemez. Bir uygulamanın bu özelliği destekleyip desteklememesi, kullanım alanlarının hedef rotasyonunun güncellenme şeklini değiştirir.
Aşağıda, kullanım alanlarının hedef dönüşünün ekran dönüşüyle nasıl senkronize edileceğini açıklayan iki tablo verilmiştir. İlk yöntemde, dört yönü de desteklerken bu işlemin nasıl yapılacağı gösterilir. İkinci yöntemde ise yalnızca cihazın varsayılan olarak döndüğü yönler ele alınır.
Uygulamanızda hangi yönergelerin uygulanacağını seçmek için:
Uygulamanızın kamerasının
Activity
kilitli bir yönü, kilidi açık bir yönü veya yön yapılandırması değişikliklerini geçersiz kılma özelliği olup olmadığını doğrulayın.Uygulamanızın kamerasının
Activity
dört cihaz yönünün (dikey, ters dikey, yatay ve ters yatay) tümünü işleyip işlemeyeceğine veya yalnızca çalıştığı cihazın varsayılan olarak desteklediği yönleri işleyip işlemeyeceğine karar verin.
Dört yönü de desteklemelidir.
Bu tabloda, cihazın yatay dikeye dönmediği durumlarda uyulması gereken belirli kurallar belirtilmiştir. Aynı durum, ters yatay moduna dönmeyen cihazlar için de geçerlidir.
Senaryo | Kurallar | Tek pencere modu | Çoklu pencere bölünmüş ekran modu |
---|---|---|---|
Kilitli olmayan yön |
Activity her oluşturulduğunda kullanım alanlarını ayarlayın (ör. Activity 'nin onCreate() geri çağırma işlevinde).
|
||
OrientationEventListener 'nin onOrientationChanged() özelliğini kullanın.
Geri çağırma içinde, kullanım alanlarının hedef rotasyonunu güncelleyin. Bu, sistemin bir yön değişikliğinden sonra bile Activity 'yi yeniden oluşturmadığı durumlarda (ör. cihaz 180 derece döndürüldüğünde) geçerlidir.
|
Ekran ters dikey yöndeyken ve cihaz varsayılan olarak ters dikey yönde dönmüyorsa da kullanılır. |
Cihaz döndürüldüğünde (ör. 90 derece) Activity öğesinin yeniden oluşturulmadığı durumları da ele alır. Bu durum, küçük form faktörlü cihazlarda uygulama ekranın yarısını kapladığında ve büyük cihazlarda uygulama ekranın üçte ikisini kapladığında gerçekleşir.
|
|
İsteğe bağlı: AndroidManifest dosyasında Activity 'nin screenOrientation özelliğini fullSensor olarak ayarlayın.
|
Bu sayede cihaz ters dikey moddayken kullanıcı arayüzü dik olur ve cihaz 90 derece döndürüldüğünde Activity sistemi tarafından yeniden oluşturulur.
|
Varsayılan olarak ters dikeye dönmeyen cihazları etkilemez. Ekran ters dikey yöndeyken çoklu pencere modu desteklenmez. | |
Kilitli yön |
Kullanım alanlarını yalnızca bir kez, Activity ilk oluşturulduğunda (ör. Activity 'ın onCreate() geri çağırma çağrısında) ayarlayın.
|
||
OrientationEventListener 'nin onOrientationChanged() özelliğini kullanın.
Geri çağırma içinde, Önizleme hariç kullanım alanlarının hedef rotasyonunu güncelleyin.
|
Cihaz döndürüldüğünde (ör. 90 derece) Activity öğesinin yeniden oluşturulmadığı durumları da ele alır. Bu durum, küçük form faktörlü cihazlarda uygulama ekranın yarısını kapladığında ve büyük cihazlarda uygulama ekranın üçte ikisini kapladığında gerçekleşir.
|
||
Yön configChanges geçersiz kılındı |
Kullanım alanlarını yalnızca bir kez, Activity ilk oluşturulduğunda (ör. Activity 'ın onCreate() geri çağırma çağrısında) ayarlayın.
|
||
OrientationEventListener 'nin onOrientationChanged() özelliğini kullanın.
Geri çağırma içinde, kullanım alanlarının hedef rotasyonunu güncelleyin.
|
Cihaz döndürüldüğünde (ör. 90 derece) Activity öğesinin yeniden oluşturulmadığı durumları da ele alır. Bu durum, küçük form faktörlü cihazlarda uygulama ekranın yarısını kapladığında ve büyük cihazlarda uygulama ekranın üçte ikisini kapladığında gerçekleşir.
|
||
İsteğe bağlı: AndroidManifest dosyasında etkinliğin screenOrientation özelliğini fullSensor olarak ayarlayın. | Cihaz ters dikey moddayken kullanıcı arayüzünün dik durmasına olanak tanır. | Varsayılan olarak ters dikeye dönmeyen cihazları etkilemez. Ekran ters dikey yöndeyken çoklu pencere modu desteklenmez. |
Yalnızca cihaz tarafından desteklenen yönleri destekleyin.
Yalnızca cihazın varsayılan olarak desteklediği yönleri destekler (yatay dikey/yatay yatay yönleri içerebilir veya içermeyebilir).
Senaryo | Kurallar | Çoklu pencere bölünmüş ekran modu |
---|---|---|
Kilitli olmayan yön |
Activity her oluşturulduğunda kullanım alanlarını ayarlayın (ör. Activity 'nin onCreate() geri çağırma işlevinde).
|
|
DisplayListener 'nin onDisplayChanged() sürümünü kullanın. Geri çağırma içinde, kullanım alanlarının hedef dönüşmesini güncelleyin (ör. cihaz 180 derece döndürüldüğünde).
|
Cihaz döndürüldüğünde (ör. 90 derece) Activity öğesinin yeniden oluşturulmadığı durumları da ele alır. Bu durum, küçük form faktörlü cihazlarda uygulama ekranın yarısını kapladığında ve büyük cihazlarda uygulama ekranın üçte ikisini kapladığında gerçekleşir.
|
|
Kilitli yön |
Kullanım alanlarını yalnızca bir kez, Activity ilk oluşturulduğunda (ör. Activity 'ın onCreate() geri çağırma çağrısında) ayarlayın.
|
|
OrientationEventListener 'nin onOrientationChanged() özelliğini kullanın.
Geri çağırma içinde, kullanım alanlarının hedef rotasyonunu güncelleyin.
|
Cihaz döndürüldüğünde (ör. 90 derece) Activity öğesinin yeniden oluşturulmadığı durumları da ele alır. Bu durum, küçük form faktörlü cihazlarda uygulama ekranın yarısını kapladığında ve büyük cihazlarda uygulama ekranın üçte ikisini kapladığında gerçekleşir.
|
|
Yön configChanges geçersiz kılındı |
Kullanım alanlarını yalnızca bir kez, Activity ilk oluşturulduğunda (ör. Activity 'ın onCreate() geri çağırma çağrısında) ayarlayın.
|
|
DisplayListener 'nin onDisplayChanged() sürümünü kullanın. Geri çağırma içinde, kullanım alanlarının hedef dönüşmesini güncelleyin (ör. cihaz 180 derece döndürüldüğünde).
|
Cihaz döndürüldüğünde (ör. 90 derece) Activity öğesinin yeniden oluşturulmadığı durumları da ele alır. Bu durum, küçük form faktörlü cihazlarda uygulama ekranın yarısını kapladığında ve büyük cihazlarda uygulama ekranın üçte ikisini kapladığında gerçekleşir.
|
Kilidi açılmış yön
Activity
, ekran yönü (dikey veya yatay gibi) cihazın fiziksel yönüyle eşleştiğinde kilidi açık bir yönde olur. Bazı cihazlar varsayılan olarak ters dikey/yatay yönü desteklemez. Cihazı dört yöne de dönmeye zorlamak için Activity
'nin screenOrientation
mülkünü fullSensor
olarak ayarlayın.
Çoklu pencere modunda, varsayılan olarak ters dikey/yatay modu desteklemeyen bir cihaz, screenOrientation
mülkü fullSensor
olarak ayarlanmış olsa bile ters dikey/yatay moduna dönmez.
<!-- The Activity has an unlocked orientation, but might not rotate to reverse portrait/landscape in single-window mode if the device doesn't support it by default. --> <activity android:name=".UnlockedOrientationActivity" /> <!-- The Activity has an unlocked orientation, and will rotate to all four orientations in single-window mode. --> <activity android:name=".UnlockedOrientationActivity" android:screenOrientation="fullSensor" />
Kilitli yön
Ekran, cihazın fiziksel yönünden bağımsız olarak aynı ekran yönünde (dikey veya yatay gibi) kaldığında kilitli bir yöndedir. Bu işlem, AndroidManifest.xml
dosyasındaki Activity
tanımında screenOrientation
özelliğini belirterek yapılabilir.
Ekran kilitli bir yöndeyken sistem, cihaz döndürüldüğünde Activity
'yi yok edip yeniden oluşturmaz.
<!-- The Activity keeps a portrait orientation even as the device rotates. --> <activity android:name=".LockedOrientationActivity" android:screenOrientation="portrait" />
Yönlendirme yapılandırması değişiklikleri geçersiz kılındı
Bir Activity
, yön yapılandırması değişikliklerini geçersiz kıldığında sistem, cihazın fiziksel yönü değiştiğinde bu yapılandırmayı yok edip yeniden oluşturmaz.
Sistem, kullanıcı arayüzünü cihazın fiziksel yönüne uyacak şekilde günceller.
<!-- The Activity's UI might not rotate in reverse portrait/landscape if the device doesn't support it by default. --> <activity android:name=".OrientationConfigChangesOverriddenActivity" android:configChanges="orientation|screenSize" /> <!-- The Activity's UI will rotate to all 4 orientations in single-window mode. --> <activity android:name=".OrientationConfigChangesOverriddenActivity" android:configChanges="orientation|screenSize" android:screenOrientation="fullSensor" />
Kamera kullanım alanları kurulumu
Yukarıda açıklanan senaryolarda kamera kullanım alanları, Activity
ilk oluşturulduğunda ayarlanabilir.
Kilidi açık yönü olan bir Activity
söz konusu olduğunda, sistem yön değişikliklerinde Activity
'yi yok edip yeniden oluşturduğundan bu kurulum cihaz her döndürüldüğünde yapılır. Bu, kullanım alanlarının hedef rotasyonunu her seferinde varsayılan olarak ekranın yönüne uyacak şekilde ayarlamasına neden olur.
Kilitli yönü olan veya yön yapılandırması değişikliklerini geçersiz kılan bir Activity
söz konusu olduğunda bu kurulum, Activity
ilk oluşturulduğunda bir kez yapılır.
class CameraActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val cameraProcessFuture = ProcessCameraProvider.getInstance(this) cameraProcessFuture.addListener(Runnable { val cameraProvider = cameraProcessFuture.get() // By default, the use cases set their target rotation to match the // display’s rotation. val preview = buildPreview() val imageAnalysis = buildImageAnalysis() val imageCapture = buildImageCapture() cameraProvider.bindToLifecycle( this, cameraSelector, preview, imageAnalysis, imageCapture) }, mainExecutor) } }
OrientationEventListener kurulumu
OrientationEventListener
kullanarak, cihazın yönü değiştikçe kamera kullanım alanlarının hedef dönüşünü sürekli olarak güncelleyebilirsiniz.
class CameraActivity : AppCompatActivity() { private val orientationEventListener by lazy { object : OrientationEventListener(this) { override fun onOrientationChanged(orientation: Int) { if (orientation == ORIENTATION_UNKNOWN) { return } val rotation = when (orientation) { in 45 until 135 -> Surface.ROTATION_270 in 135 until 225 -> Surface.ROTATION_180 in 225 until 315 -> Surface.ROTATION_90 else -> Surface.ROTATION_0 } imageAnalysis.targetRotation = rotation imageCapture.targetRotation = rotation } } } override fun onStart() { super.onStart() orientationEventListener.enable() } override fun onStop() { super.onStop() orientationEventListener.disable() } }
DisplayListener kurulumu
DisplayListener
kullanmak, belirli durumlarda kamera kullanım alanlarının hedef dönüşünü güncellemenize olanak tanır. Örneğin, sistem cihaz 180 derece döndükten sonra Activity
'ı yok edip yeniden oluşturmadığında.
class CameraActivity : AppCompatActivity() { private val displayListener = object : DisplayManager.DisplayListener { override fun onDisplayChanged(displayId: Int) { if (rootView.display.displayId == displayId) { val rotation = rootView.display.rotation imageAnalysis.targetRotation = rotation imageCapture.targetRotation = rotation } } override fun onDisplayAdded(displayId: Int) { } override fun onDisplayRemoved(displayId: Int) { } } override fun onStart() { super.onStart() val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager displayManager.registerDisplayListener(displayListener, null) } override fun onStop() { super.onStop() val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager displayManager.unregisterDisplayListener(displayListener) } }