Kamera önizleme

Not: Bu sayfa, Kamera2 paketiyle ilgilidir. Uygulamanız Camera2'nin belirli, alt düzey özelliklerini gerektirmiyorsa KameraX'i kullanmanızı öneririz. Hem CameraX hem de Camera2, Android 5.0 (API düzeyi 21) ve sonraki sürümleri destekler.

Android cihazlarda kameralar ve kamera önizlemeleri her zaman aynı yönde olmaz.

Kamera telefon, tablet veya bilgisayar fark etmeksizin tüm cihazlarda sabit bir konumdadır. Cihazın yönü değiştiğinde kamera yönü değişir.

Bunun sonucunda kamera uygulamaları, genellikle cihazın yönü ile kamera önizlemesinin en boy oranı arasında sabit bir ilişki olduğunu varsayar. Telefon dikey yönde olduğunda kamera önizlemesinin genişliğinden daha uzun olduğu varsayılır. Telefon (ve kamera) yatay konuma getirildiğinde kamera önizlemesinin yüksekliğinden daha geniş olması beklenir.

Ancak bu varsayımlar, hem katlanabilir cihazlar hem de çoklu pencere ve çoklu ekran gibi görüntüleme modları gibi yeni form faktörleriyle çelişiyor. Katlanabilir cihazlar yön değiştirmeden ekran boyutunu ve en boy oranını değiştirir. Çoklu pencere modu, kamera uygulamalarını ekranın bir kısmıyla sınırlandırarak cihaz yönünden bağımsız olarak kamera önizlemesini ölçeklendirir. Çoklu ekran modu, birincil ekranla aynı yönde olmayabilecek ikincil ekranların kullanılmasını sağlar.

Kamera yönü

Android Uyumluluk Tanımı, kamera görüntü sensörünün, kameranın uzun boyutunun ekranın uzun boyutuyla hizalanacak şekilde yönlendirilmesi gerektiği anlamına gelir. Yani, cihaz yatay yönde tutulduğunda kameraların yatay yönde resim çekmesi GEREKİR. Bu, cihazın doğal yönü ne olursa olsun geçerlidir. Yani, hem yatay birincil hem de dikey birincil cihazlar için geçerlidir.

Kameradan ekrana geçiş, kamera uygulamasında kamera vizörünün görüntüleme alanını en üst düzeye çıkarır. Ayrıca, görüntü sensörleri verilerini genellikle yatay en boy oranlarında verir. Bu oran en yaygın olanı 4:3'tür.

Telefon ve kamera sensörü dikey yönde.
Şekil 1. Telefon ve kameranın sensör yönüyle ilgili tipik ilişki.

Kamera sensörünün doğal yönü yataydır. Şekil 1'de ön kameranın sensörü (kamera ekranla aynı yönü gösterir), Android Uyumluluk Tanımı'na uymak için telefona göre 270 derece döndürülmektedir.

camera2 API'si, sensör dönüşünü uygulamalara maruz bırakmak için bir SENSOR_ORIENTATION sabiti içerir. Cihaz, çoğu telefonda ve tablette sensör yönünü bildirerek ön kameralar için 270 derece, arka kameralar içinse 90 derece (cihazın arkasından bakış noktası) sensör yönü bildirir. Bu değerler sensörün uzun kenarını cihazın uzun kenarıyla hizalar. Dizüstü bilgisayar kameraları genellikle 0 veya 180 derece sensör yönü bildirir.

Kamera resim sensörleri, verilerini sensörün doğal yönünde (yatay) döndürdüğünden (görüntü arabelleği) kamera önizlemesinin cihazın doğal yönünde dik görünmesi için SENSOR_ORIENTATION tarafından belirtilen derece kadar döndürülmesi gerekir. Ön kameralarda saat yönünün tersine, arka kameralarda ise saat yönünde döndürme hareketini görürsünüz.

Örneğin, şekil 1'deki ön kamera için kamera sensörünün oluşturduğu görüntü tamponu aşağıdaki gibi görünür:

Kamera sensörü yatay yönde döndürüldü ve resim yan, sol üstte olacak şekilde ayarlandı.

Önizlemenin yönünün cihaz yönüyle eşleşmesi için resim saat yönünün tersine 270 derece döndürülmelidir:

Dikey yönde kamera sensörü ve resim dik konumda.

Arkaya bakan bir kamera yukarıdaki tamponla aynı yönde bir görüntü arabelleği üretir, ancak SENSOR_ORIENTATION 90 derecedir. Sonuç olarak, arabellek saat yönünde 90 derece döndürüldü.

Cihaz döndürme

Cihaz döndürme, bir cihazın doğal yönünden döndürüldüğü derece sayısıdır. Örneğin, yatay yöndeki bir telefonun dönüş yönüne bağlı olarak cihazı 90 veya 270 derece döner.

Kamera önizlemesinin dik görünmesi için, kamera sensörü görüntü arabelleğinin, cihazın dönüşüyle aynı sayıda (sensör yönünün derecesine ek olarak) döndürülmesi gerekir.

Yön hesaplaması

Kamera önizlemesinin doğru yönü, sensör yönü ve cihaz dönüşünü dikkate alır.

Sensör görüntüsü arabelleğinin genel dönüşü aşağıdaki formül kullanılarak hesaplanabilir:

rotation = (sensorOrientationDegrees - deviceOrientationDegrees * sign + 360) % 360

Burada sign ön kamera için 1, arka kameralar için -1 olur.

Ön kameralarda görüntü arabelleği saat yönünün tersine (sensörün doğal yönünden) döndürülür. Arka kameralarda sensör görüntü arabelleği saat yönünde döndürülür.

deviceOrientationDegrees * sign + 360 ifadesi, arkaya bakan kameralarda cihaz döndürme yönünü saat yönünün tersine çevirir (örneğin, saat yönünün tersine 270 dereceyi saat yönünün tersine 90 dereceye dönüştürür). Modül işlemi, sonucu 360 derecenin altında olacak şekilde ölçeklendirir (örneğin, 540 derece döndürmeyi 180 dereceye ölçeklendirme).

Farklı API'ler, cihaz rotasyonunu farklı şekilde bildirir:

  • Display#getRotation() cihazın saat yönünün tersine dönmesini sağlar (kullanıcının bakış açısından). Bu değer, olduğu gibi yukarıdaki formüle eklenir.
  • OrientationEventListener#onOrientationChanged() cihazı saat yönünde döndürür (kullanıcının bakış açısından). Yukarıdaki formülde kullanılacak değeri yoksayın.

Ön kameralar

Hem kamera önizlemesi hem de sensör yatay yönde ve sensör sağ üstte olacak şekilde gösteriliyor.
Şekil 2. Telefondaki kamera önizlemesi ve sensör, 90 derece yatay yöne döndürüldü.

Kamera sensörü tarafından üretilen görüntü arabelleği Şekil 2'de gösterilmiştir:

Yatay yönde kamera sensörü ve resim dik.

Sensör yönünün ayarlanması için arabellek saat yönünün tersine 270 derece döndürülmelidir (yukarıdaki Kamera yönü bölümüne bakın):

Kamera sensörü dikey yöne döndürüldü ve resim yan olacak şekilde,
            sağ üstte.

Daha sonra, cihaz döndürmesini hesaba katmak için tampon saat yönünün tersine 90 derece döndürülür. Böylece Şekil 2'de kamera önizlemesinin doğru yönü elde edilir:

Kamera sensörü, görüntü dik olacak şekilde yatay yöne döndürüldü.

Kamera sağa doğru yatay yönde döndürüldü:

Kamera önizlemesi ve sensör yatay yönde ancak sensör ters.
Şekil 3. Telefondaki kamera önizlemesi ve sensör, yatay yöne 270 derece (veya -90 derece) döndürüldü.

Resim arabelleği şöyledir:

Kamera sensörü, görüntü baş aşağı olacak şekilde yatay yöne döndürüldü.

Sensör yönünün ayarlanması için arabellek saat yönünün tersine 270 derece döndürülmelidir:

Kamera sensörü, resim yan, sol üstte olacak şekilde dikey yönde derecelendirildi.

Daha sonra tampon, cihaz döndürmesini hesaba katmak için saat yönünün tersine 270 derece daha döndürülür:

Kamera sensörü, görüntü dik olacak şekilde yatay yöne döndürüldü.

Arka kameralar

Arka kameralarda genellikle 90 derece sensör yönü bulunur (cihazın arkasından bakıldığında). Kamera önizlemesinin yönü ayarlanırken, sensör görüntüsü arabelleği sensör dönüşü kadar saat yönünde döndürülür (ön kameralarda olduğu gibi saat yönünün tersine değil) ve ardından resim arabelleği, cihazın döndürme miktarına göre saat yönünün tersine döndürülür.

Kamera önizlemesi ve sensör yatay yönde ancak sensör ters.
Şekil 4. Arka kamerası yatay yönde (270 veya -90 derece döndürüldü) telefon.

Kamera sensöründen gelen görüntü arabelleği, Şekil 4'te gösterilmiştir:

Kamera sensörü, görüntü baş aşağı olacak şekilde yatay yöne döndürüldü.

Sensör yönünün ayarlanması için arabellek saat yönünde 90 derece döndürülmelidir:

Kamera sensörü, resim yan, sol üstte olacak şekilde dikey yönde derecelendirildi.

Daha sonra tampon, cihaz dönüşünü hesaba katmak için saat yönünün tersine 270 derece döndürülür:

Kamera sensörü, görüntü dik olacak şekilde yatay yöne döndürüldü.

En boy oranı

Ekran en boy oranı, cihazın yönü değiştiğinde ve aynı zamanda katlanabilir cihazlar katlanıp açıldığında, çoklu pencereli ortamlarda pencereler yeniden boyutlandırıldığında ve uygulamalar ikincil ekranlarda açıldığında değişir.

Kamera sensörü görüntü arabelleği, cihazın yönü değişirken veya olmadan kullanıcı arayüzü dinamik olarak değişirken vizör kullanıcı arayüzü öğesinin yönü ve en boy oranıyla eşleşecek şekilde yönlenmeli ve ölçeklendirilmelidir.

Yeni form faktörlerinde veya çok pencereli ya da çok ekranlı ortamlarda, uygulamanız kamera önizlemesinin cihazla aynı yöne (dikey veya yatay) sahip olduğunu varsayarsa önizlemeniz yanlış yönlenmiş, doğru ölçeklendirilmemiş ya da her iki durumda da olabilir.

Dikey kamera önizlemesi yana doğru çevrilmiş olan katlanabilir katlanabilir cihaz.
Şekil 5. Katlanabilir cihazlar dikey yönden yatay düzene geçer ancak kamera sensörü dikey yönde kalır.

Şekil 5'te uygulama yanlışlıkla cihazın saat yönünün tersine 90 derece döndürüldüğünü düşünmüş ve bu nedenle uygulama, önizlemeyi aynı miktarda döndürmüştür.

Kamera önizlemesi dik ancak yanlış ölçeklendirme nedeniyle basılmış olan katlanabilir cihaz.
Şekil 6. Katlanabilir cihazlar dikey yönden yatay düzene geçer ancak kamera sensörü dikey yönde kalır.

Şekil 6'da uygulama, resim arabelleğinin en boy oranını kamera önizlemesi kullanıcı arayüzü öğesinin yeni boyutlarına uyacak şekilde doğru ölçeklendirilmesi için ayarlamamıştır.

Sabit yönlü kamera uygulamaları genellikle katlanabilir cihazlarda ve dizüstü bilgisayar gibi diğer büyük ekranlı cihazlarda sorun yaşar:

Dizüstü bilgisayardaki kamera önizlemesi dik ancak uygulamanın kullanıcı arayüzü yan duruyor.
Şekil 7. Dizüstü bilgisayarda sabit yönlü dikey uygulaması.

Şekil 7'de kamera uygulamasının kullanıcı arayüzü yan durmaktadır, çünkü uygulamanın yönü yalnızca dikey olarak tanımlanmıştır. Vizör resmi, kamera sensörüne göre doğru yerleştirilmiştir.

İçe doğru dikey mod

Çoklu pencere modunu (resizeableActivity="false") desteklemeyen ve yönünü kısıtlayan (screenOrientation="portrait" veya screenOrientation="landscape") kamera uygulamaları, kamera önizlemesinin doğru yöne gitmesi için büyük ekranlı cihazlarda dikey dikey modda yerleştirilebilir.

Ekran en boy oranı yatay olsa bile dikey yönlü yalnızca dikey yönlü uygulamalar için dikey mod sinemaskop. Yalnızca yatay uygulamalar, ekranın en boy oranı dikey olsa da yatay yönde sinemaskop yapılır. Kamera resmi, uygulamanın kullanıcı arayüzüne uyacak şekilde döndürülür, kamera önizlemesinin en boy oranına uyacak şekilde kırpılır ve ardından önizlemeyi dolduracak şekilde ölçeklendirilir.

Kamera görüntüsü sensörünün en boy oranı ile uygulamanın birincil etkinliğinin en boy oranı eşleşmediğinde içe dikey mod tetiklenir.

Dizüstü bilgisayarda uygun dikey yönde kamera önizlemesi ve uygulama kullanıcı arayüzü.
            Geniş önizleme resmi, dikey yöne sığacak şekilde ölçeklendirilir ve kırpılır.
Şekil 8. Dizüstü bilgisayarda içeriye doğru dikey modda sabit yönlü dikey uygulama.

Şekil 8'de yalnızca dikey kamera uygulaması, kullanıcı arayüzünü dizüstü bilgisayar ekranında dik olacak şekilde döndürülmüştür. Dikey uygulama ile yatay ekran arasındaki en boy oranı farklı olduğundan uygulama sinemaskop yapılır. Kamera önizleme resmi, uygulamanın kullanıcı arayüzü dönüşünü telafi etmek için döndürüldü (içe doğru dikey mod nedeniyle) ve resim, dikey yöne uyacak şekilde kırpıldı ve ölçeklendirildi. Böylece görüş alanı azaltıldı.

Döndürme, kırpma, ölçekleme

İçe aktarılan dikey mod, yatay en boy oranına sahip bir ekranda yalnızca dikey kamera uygulaması için çağrılır:

Dizüstü bilgisayardaki kamera önizlemesi dik ancak uygulamanın kullanıcı arayüzü yan duruyor.
Şekil 9. Dizüstü bilgisayarda sabit yönlü dikey uygulaması.

Uygulamaya dikey yönde sinemaskop eklenir:

Uygulama dikey yöne döndürüldü ve sinemaskoplu. Resim yan yatmış, sağdadır.

Kamera görüntüsü, uygulamanın yönünü ayarlamak için 90 derece döndürülür:

Sensör görüntüsü, dik olması için 90 derece döndürüldü.

Resim, kamera önizlemesinin en boy oranına göre kırpılır ve ardından önizlemeyi dolduracak şekilde ölçeklendirilir (görüş alanı küçültülür):

Kırpılmış kamera resmi, kamera önizlemesini doldurmak için ölçeklendirildi.

Katlanabilir cihazlarda ekranın en boy oranı yatayken kamera sensörünün yönü dikey olabilir:

Kamera önizlemesi ve uygulama kullanıcı arayüzü, yana doğru çevrilmiş geniş, katlanmamış ekran.
Şekil 10. Yalnızca dikey kamera uygulamasının yanı sıra kamera sensörü ve ekranın farklı en boy oranlarına sahip katlanmamış cihaz.

Kamera önizlemesi, sensör yönünü ayarlamak üzere döndürüldüğünden, görüntü vizörde doğru hedeflenir ancak yalnızca dikey görünüm modu yan yanadır.

Uygulamayı ve kamera önizlemesini doğru yönlendirmek için dikey modun yalnızca dikey yönde sinemaskop yapması gerekir:

Katlanabilir cihazda dik kamera önizlemesine sahip, dikey yönde sinemaskoplu uygulama.

API

Android 12 (API düzeyi 31) sürümünden itibaren uygulamalar, CaptureRequest sınıfının SCALER_ROTATE_AND_CROP özelliği aracılığıyla içe yerleştirilmiş dikey modu açıkça kontrol edebilmektedir.

Varsayılan değer olan SCALER_ROTATE_AND_CROP_AUTO, sistemin dikey modu çağırmasını sağlar. SCALER_ROTATE_AND_CROP_90, yukarıda açıklanan dikey modun davranışıdır.

Bazı cihazlar tüm SCALER_ROTATE_AND_CROP değerlerini desteklemez. Desteklenen değerlerin listesini almak için CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES bağlantısını inceleyin.

KameraX

Jetpack CameraX kitaplığı, sensör yönü ve cihaz döndürme özelliğine uygun bir kamera vizörü oluşturmayı basit bir iş haline getirir.

PreviewView düzen öğesi; sensör yönü, cihaz döndürme ve ölçeklendirme için otomatik olarak ayarlanan bir kamera önizlemesi oluşturur. PreviewView, FILL_CENTER ölçek türünü uygulayarak kamera resminin en boy oranını korur. Bu ölçek, resmi ortalasa da PreviewView boyutlarıyla eşleşecek şekilde kırpabilir. Kamera resmini sinemaskop yapmak için ölçek türünü FIT_CENTER olarak ayarlayın.

PreviewView ile kamera önizlemesi oluşturmayla ilgili temel bilgileri öğrenmek için Önizleme uygulama konusuna göz atın.

Eksiksiz bir örnek uygulama için GitHub'daki CameraXBasic deposuna göz atın.

Kamera Vizörü

Önizleme kullanım alanına benzer şekilde, KameraViewfinder kitaplığı da kamera önizlemesinin oluşturulmasını basitleştirmek için bir dizi araç sunar. CameraX Core'a bağlı olmadığından, bunu mevcut Camera2 kod tabanınıza sorunsuz bir şekilde entegre edebilirsiniz.

Surface'i doğrudan kullanmak yerine, Kamera2'nin kamera feed'ini görüntülemek için CameraViewfinder widget'ını kullanabilirsiniz.

CameraViewfinder, kamera feed'ini görüntülemek için dahili olarak bir TextureView veya SurfaceView kullanır ve vizörü doğru şekilde görüntülemek için bunlarda gerekli dönüşümleri uygular. Bu işlem, video öğelerinin en boy oranını, ölçeğini ve döndürme yönünü düzeltmeyi içerir.

CameraViewfinder nesnesinden yüzey istemek için bir ViewfinderSurfaceRequest oluşturmanız gerekir.

Bu istek, CameraCharacteristics tarafından sağlanan yüzey çözünürlüğü ve kamera cihaz bilgileriyle ilgili şartları içermektedir.

requestSurfaceAsync() çağrıldığında istek, TextureView veya SurfaceView olan yüzey sağlayıcısına gönderilir ve Surface ListenableFuture alır.

markSurfaceSafeToRelease() çağrıldığında, yüzey sağlayıcıya yüzeye ihtiyaç olmadığı ve ilgili kaynakların serbest bırakılabileceği bildirilir.

Kotlin


fun startCamera(){
    val previewResolution = Size(width, height)
    val viewfinderSurfaceRequest =
        ViewfinderSurfaceRequest(previewResolution, characteristics)
    val surfaceListenableFuture =
        cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest)

    Futures.addCallback(surfaceListenableFuture, object : FutureCallback<Surface> {
        override fun onSuccess(surface: Surface) {
            /* create a CaptureSession using this surface as usual */
        }
        override fun onFailure(t: Throwable) { /* something went wrong */}
    }, ContextCompat.getMainExecutor(context))
}

Java


    void startCamera(){
        Size previewResolution = new Size(width, height);
        ViewfinderSurfaceRequest viewfinderSurfaceRequest =
                new ViewfinderSurfaceRequest(previewResolution, characteristics);
        ListenableFuture<Surface> surfaceListenableFuture =
                cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest);

        Futures.addCallback(surfaceListenableFuture, new FutureCallback<Surface>() {
            @Override
            public void onSuccess(Surface result) {
                /* create a CaptureSession using this surface as usual */
            }
            @Override public void onFailure(Throwable t) { /* something went wrong */}
        },  ContextCompat.getMainExecutor(context));
    }

Yüzey Görünümü

SurfaceView, önizlemenin işleme alınmasını gerektirmiyorsa ve animasyonlu değilse kamera önizlemesi oluşturmak için kolay bir yaklaşımdır.

SurfaceView, kamera sensörü görüntü arabelleğini, hem sensör yönünü hem de cihaz döndürmesini hesaba katarak ekran yönüyle eşleşecek şekilde otomatik olarak döndürür. Ancak resim arabelleği, en boy oranı dikkate alınmadan SurfaceView boyutlarına sığacak şekilde ölçeklendirilir.

Resim arabelleğinin en boy oranının SurfaceView en boy oranıyla eşleştiğinden emin olmanız gerekir. Bu oranı, bileşenin onMeasure() yöntemindeki SurfaceView içeriğini ölçeklendirerek elde edebilirsiniz:

(computeRelativeRotation() kaynak kodu aşağıdaki Göreli rotasyon bölümündedir.)

Kotlin

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    val width = MeasureSpec.getSize(widthMeasureSpec)
    val height = MeasureSpec.getSize(heightMeasureSpec)

    val relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees)

    if (previewWidth > 0f && previewHeight > 0f) {
        /* Scale factor required to scale the preview to its original size on the x-axis. */
        val scaleX =
            if (relativeRotation % 180 == 0) {
                width.toFloat() / previewWidth
            } else {
                width.toFloat() / previewHeight
            }
        /* Scale factor required to scale the preview to its original size on the y-axis. */
        val scaleY =
            if (relativeRotation % 180 == 0) {
                height.toFloat() / previewHeight
            } else {
                height.toFloat() / previewWidth
            }

        /* Scale factor required to fit the preview to the SurfaceView size. */
        val finalScale = min(scaleX, scaleY)

        setScaleX(1 / scaleX * finalScale)
        setScaleY(1 / scaleY * finalScale)
    }
    setMeasuredDimension(width, height)
}

Java

@Override
void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);

    int relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees);

    if (previewWidth > 0f && previewHeight > 0f) {

        /* Scale factor required to scale the preview to its original size on the x-axis. */
        float scaleX = (relativeRotation % 180 == 0)
                       ? (float) width / previewWidth
                       : (float) width / previewHeight;

        /* Scale factor required to scale the preview to its original size on the y-axis. */
        float scaleY = (relativeRotation % 180 == 0)
                       ? (float) height / previewHeight
                       : (float) height / previewWidth;

        /* Scale factor required to fit the preview to the SurfaceView size. */
        float finalScale = Math.min(scaleX, scaleY);

        setScaleX(1 / scaleX * finalScale);
        setScaleY(1 / scaleY * finalScale);
    }
    setMeasuredDimension(width, height);
}

SurfaceView uygulamasını kamera önizlemesi olarak uygulama hakkında daha fazla bilgi için Kamera yönleri bölümüne bakın.

Doku Görünümü

TextureView, SurfaceView uygulamasından daha düşük performans ve daha fazla iş sunar. Ancak TextureView, size kamera önizlemesi üzerinde maksimum kontrol sağlar.

TextureView, sensör görüntü arabelleğini sensör yönüne göre döndürür, ancak cihaz döndürmesini veya önizleme ölçeklendirmesini işlemez.

Ölçeklendirme ve döndürme, bir Matris dönüşümüne kodlanabilir. TextureView cihazının doğru şekilde nasıl ölçeklendirilip döndürüleceğini öğrenmek için Kamera uygulamanızda yeniden boyutlandırılabilir yüzeyleri destekleme konusuna bakın.

Göreli rotasyon

Kamera sensörünün göreli dönüşü, kamera sensörü çıkışını cihaz yönüyle hizalamak için gereken dönüş miktarıdır.

Göreli döndürme, SurfaceView ve TextureView gibi bileşenler tarafından, önizleme resmi için x ve y ölçeklendirme faktörlerini belirlemek amacıyla kullanılır. Ayrıca sensör görüntü arabelleğinin dönüşünü belirlemek için de kullanılır.

CameraCharacteristics ve Surface sınıfları, kamera sensörünün göreli dönüşünün hesaplanmasını sağlar:

Kotlin

/**
 * Computes rotation required to transform the camera sensor output orientation to the
 * device's current orientation in degrees.
 *
 * @param characteristics The CameraCharacteristics to query for the sensor orientation.
 * @param surfaceRotationDegrees The current device orientation as a Surface constant.
 * @return Relative rotation of the camera sensor output.
 */
public fun computeRelativeRotation(
    characteristics: CameraCharacteristics,
    surfaceRotationDegrees: Int
): Int {
    val sensorOrientationDegrees =
        characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION)!!

    // Reverse device orientation for back-facing cameras.
    val sign = if (characteristics.get(CameraCharacteristics.LENS_FACING) ==
        CameraCharacteristics.LENS_FACING_FRONT
    ) 1 else -1

    // Calculate desired orientation relative to camera orientation to make
    // the image upright relative to the device orientation.
    return (sensorOrientationDegrees - surfaceRotationDegrees * sign + 360) % 360
}

Java

/**
 * Computes rotation required to transform the camera sensor output orientation to the
 * device's current orientation in degrees.
 *
 * @param characteristics The CameraCharacteristics to query for the sensor orientation.
 * @param surfaceRotationDegrees The current device orientation as a Surface constant.
 * @return Relative rotation of the camera sensor output.
 */
public int computeRelativeRotation(
    CameraCharacteristics characteristics,
    int surfaceRotationDegrees
){
    Integer sensorOrientationDegrees =
        characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);

    // Reverse device orientation for back-facing cameras.
    int sign = characteristics.get(CameraCharacteristics.LENS_FACING) ==
        CameraCharacteristics.LENS_FACING_FRONT ? 1 : -1;

    // Calculate desired orientation relative to camera orientation to make
    // the image upright relative to the device orientation.
    return (sensorOrientationDegrees - surfaceRotationDegrees * sign + 360) % 360;
}

Aralık metrikleri

Kamera vizörünün boyutlarını belirlemek için ekran boyutu kullanılmamalıdır. Kamera uygulaması, mobil cihazlarda çoklu pencere modunda veya ChromeOS'te serbest modda çalışıyor olabilir.

WindowManager#getCurrentWindowMetrics() (API düzeyi 30'da eklenir), ekranın boyutu yerine uygulama penceresinin boyutunu döndürür. Jetpack WindowManager kitaplık yöntemleri WindowMetricsCalculator#computeCurrentWindowMetrics() ve WindowInfoTracker#currentWindowMetrics() API düzeyi 14'e kadar geriye dönük uyumlulukla benzer bir destek sunar.

180 derece döndürme

Bir cihazın 180 derece döndürülmesi (ör. doğal yönden doğal yöne baş aşağı), onConfigurationChanged() geri çağırma işlemini tetiklemez. Bu nedenle kamera önizlemesi ters olabilir.

180 derecelik döndürmeyi algılamak için bir DisplayListener uygulayın ve geri çağırmanın içinde onDisplayChanged() Display#getRotation() çağrısıyla cihaz döndürmesini kontrol edin.

Özel kaynaklar

Android 10'dan önce, çoklu pencere ortamında yalnızca en üstte görünen etkinlik RESUMED durumundaydı. Sistem, hangi etkinliğin devam ettirildiğine dair hiçbir gösterge sunmadığından bu durum kullanıcıların kafasını karıştırdı.

Android 10 (API düzeyi 29), görünür tüm etkinliklerin RESUMED durumunda olduğu çoklu devam ettirme özelliğini kullanıma sundu. Örneğin, şeffaf bir etkinlik etkinliğin üzerinde yer alıyorsa veya etkinliğe odaklanılamıyorsa (ör. pencere içinde pencere modu) görünür etkinlikler yine de PAUSED durumunu girebilir (bkz. Pencere içinde pencere desteği).

Kamerayı, mikrofonu veya API düzeyi 29 ya da üstü bir özel ya da tekli kaynağı kullanan bir uygulama, çoklu devam ettirmeyi desteklemelidir. Örneğin, devam ettirilen üç etkinlik kamerayı kullanmak isterse yalnızca biri bu özel kaynağa erişebilir. Daha yüksek öncelikli bir etkinlik tarafından kameraya öncelikli erişimin farkında olmak için her etkinlikte bir onDisconnected() geri çağırması uygulanmalıdır.

Daha fazla bilgi için Çoklu devam ettirme bölümüne bakın.

Ek kaynaklar