Not: Bu sayfa Kamera2 paketiyle ilgilidir. Uygulamanız için Kamera2'nin belirli, alt düzey özellikleri gerekmiyorsa, KameraX'i kullanmanızı öneririz. Hem CameraX hem de Camera2, Android 5.0 (API düzeyi 21) ve sonraki sürümleri destekler.
Android destekli tek bir cihazın birden fazla kamerası olabilir. Her kamera bir
CameraDevice
CameraDevice
ise aynı anda birden fazla yayın yapabilir.
Bunun nedenlerinden biri de tek bir akış ile sıralı kamera karelerinin
bir CameraDevice
cihazındaki
vizör, diğerleri ise fotoğraf çekmek veya video çekmek için kullanılabilir
Bu akışlar, ham kareleri işleyen paralel ardışık düzenler görevi görür
her seferinde tek bir kare atlayıp kameradan çıkın:
Paralel işleme, kullanıcıya bağlı olarak CPU, GPU veya diğer işlemcilerden gelen mevcut işlem gücü. gelen karelere ayak uyduramaz ve bu kareleri bırakmaya başlar.
Her ardışık düzenin kendi çıkış biçimi vardır. Gelen ham veriler,
uygun biçime otomatik olarak
örtülü mantıka göre çıktı biçimi
her bir ardışık düzen ile ilişkilendirilir. Bu sayfa boyunca kullanılan CameraDevice
kod örnekleri belirli değildir, bu nedenle önce tanımlayın
mevcut tüm kameraları kontrol edin.
CameraDevice
kullanarak
CameraCaptureSession
,
oluşturabilirsiniz.CameraDevice
Bir CameraDevice
,
çerçeve yapılandırmasını CameraCaptureSession
kullanarak oluşturun. İlgili içeriği oluşturmak için kullanılan
yapılandırma, otomatik odaklama, diyafram açıklığı, efektler ve
ve maruz kalmayı
seçin. Donanım kısıtlamaları nedeniyle yalnızca tek bir yapılandırma
Buna kamera sensöründe herhangi bir zamanda aktif olmaya
active yapılandırması.
Bununla birlikte, Akış Kullanım Alanları, CameraDevice
ürününün önceki yollarını geliştirir ve genişletir.
görüntü yakalama oturumlarını canlı oynatabilirsiniz. Bu şekilde kamera akışını optimize edebilirsiniz.
kullanım alanına sahip olursunuz. Örneğin, optimizasyon sırasında pil ömrünü uzatabilir
görüntülü görüşme de yapabilirsiniz.
CameraCaptureSession
,
CameraDevice
. Oturum oluşturulduğunda ardışık düzen ekleyemez veya kaldıramazsınız.
CameraCaptureSession
,
CaptureRequest
,
bunlar etkin yapılandırma haline gelir.
CaptureRequest
, sıraya bir yapılandırma ekler ve en az bir yapılandırma
çerçeve almak için mevcut ardışık düzenlerden birinin veya tümünün
CameraDevice
. Bir yakalamanın kullanım süresi boyunca çok sayıda yakalama isteği gönderebilirsiniz
kabul edilir. Her istek, etkin yapılandırmayı ve çıkış grubunu değiştirebilir
ardışık düzen oluşturabilirsiniz.
Daha iyi performans için akış kullanım alanlarını kullanın
Akış Kullanım Alanları, Camera2 yakalama performansını artırmanın bir yoludur anlamına gelir. Parametreleri ayarlamak için donanım cihazına daha fazla bilgi verirler. belirli bir göreviniz için daha iyi bir kamera deneyimi sunar.
Bu
kamera cihazının, kamera donanımı ve yazılım ardışık düzenlerini optimize etmesini sağlar
kullanıcı senaryolarına göre
değiştirmeniz gerekir. Akış Kullanımı hakkında daha fazla bilgi için
Destek kayıtları için bkz. setStreamUseCase
.
Akış Kullanım Alanları belirli bir kamera akışının nasıl kullanılacağını belirtmenizi sağlar
oluşturmaya ek olarak,
CameraDevice.createCaptureRequest()
Bu şekilde, kamera donanımı
optimizasyonu
hassas ayarlama, sensör modu veya kamera sensörü ayarları gibi
belirli kullanım alanları için uygun olan
kalite veya gecikme dengeleridir.
Akış Kullanım Alanları şunları içerir:
DEFAULT
: Mevcut tüm uygulama davranışlarını kapsar. Eşdeğer, akış kullanım alanı ayarlayabilirsiniz.PREVIEW
: Vizör veya uygulama içi resim analizi için önerilir.STILL_CAPTURE
: Yüksek kaliteli yüksek çözünürlüklü çekim için optimize edilmiştir, ancak önizlemeye benzer kare hızlarını koruması beklenir.VIDEO_RECORD
: Yüksek kalite dahil yüksek kaliteli video yakalama için optimize edilmiştir cihaz tarafından destekleniyorsa ve uygulama tarafından etkinleştirilmişse görüntü sabitleme. Bu seçenek, gerçek zamanlıya göre önemli bir gecikmeye yol açan çıkış kareleri üretebilir. Böylece en yüksek kalitede sabitleme veya diğer işleme süreçleri elde edebilirsiniz.VIDEO_CALL
: Güç tüketiminin önemli olduğu uzun süreli kamera kullanımları için önerilir. emin olun.PREVIEW_VIDEO_STILL
: Sosyal medya uygulamaları veya tek akış kullanımı için önerilir. durumlarda işe yarar. Bu çok amaçlı bir yayın.VENDOR_START
: OEM tarafından tanımlanan kullanım alanları için kullanılır.
CameraCaptureSession oluşturma
Kamera oturumu oluşturmak için bir veya daha fazla çıkış arabelleği sağlayın. uygulamanızın çıkış çerçeveleri yazabileceğini lütfen unutmayın. Her arabellek, bir ardışık düzeni temsil eder. Şunu yapmalısınız: çerçevenin yapılandırabilmesi için kamerayı kullanmaya başlamadan önce çerçeveleri göndermek için cihazın dahili ardışık düzenlerini destekler ve bellek arabellekleri ayırır ihtiyaç duyulan çıkış hedeflerine yönlendirirsiniz.
Aşağıdaki kod snippet'inde, iki üçlü kamera oturumuna nasıl hazırlayabileceğiniz
çıktı arabellekleri içerir. Bunlardan biri
SurfaceView
ve başka bir tanesi bir
ImageReader
. PREVIEW
Akış Kullanım Alanı previewSurface
ve
STILL_CAPTURE
Akış Kullanımı
Case to imReaderSurface
, cihaz donanımının bu akışları bile optimize etmesini sağlar.
devam edebilir.
Kotlin
// Retrieve the target surfaces, which might be coming from a number of places: // 1. SurfaceView, if you want to display the image directly to the user // 2. ImageReader, if you want to read each frame or perform frame-by-frame // analysis // 3. OpenGL Texture or TextureView, although discouraged for maintainability reasons // 4. RenderScript.Allocation, if you want to do parallel processing val surfaceView = findViewById<SurfaceView>(...) val imageReader = ImageReader.newInstance(...) // Remember to call this only *after* SurfaceHolder.Callback.surfaceCreated() val previewSurface = surfaceView.holder.surface val imReaderSurface = imageReader.surface val targets = listOf(previewSurface, imReaderSurface) // Create a capture session using the predefined targets; this also involves // defining the session state callback to be notified of when the session is // ready // Setup Stream Use Case while setting up your Output Configuration. @RequiresApi(Build.VERSION_CODES.TIRAMISU) fun configureSession(device: CameraDevice, targets: List<Surface>){ val configs = mutableListOf<OutputConfiguration>() val streamUseCase = CameraMetadata .SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL targets.forEach { val config = OutputConfiguration(it) config.streamUseCase = streamUseCase.toLong() configs.add(config) } ... device.createCaptureSession(session) }
Java
// Retrieve the target surfaces, which might be coming from a number of places: // 1. SurfaceView, if you want to display the image directly to the user // 2. ImageReader, if you want to read each frame or perform frame-by-frame analysis // 3. RenderScript.Allocation, if you want to do parallel processing // 4. OpenGL Texture or TextureView, although discouraged for maintainability reasons Surface surfaceView = findViewById<SurfaceView>(...); ImageReader imageReader = ImageReader.newInstance(...); // Remember to call this only *after* SurfaceHolder.Callback.surfaceCreated() Surface previewSurface = surfaceView.getHolder().getSurface(); Surface imageSurface = imageReader.getSurface(); List<Surface> targets = Arrays.asList(previewSurface, imageSurface); // Create a capture session using the predefined targets; this also involves defining the // session state callback to be notified of when the session is ready private void configureSession(CameraDevice device, List<Surface> targets){ ArrayList<OutputConfiguration> configs= new ArrayList() String streamUseCase= CameraMetadata .SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL for(Surface s : targets){ OutputConfiguration config = new OutputConfiguration(s) config.setStreamUseCase(String.toLong(streamUseCase)) configs.add(config) } device.createCaptureSession(session) }
Bu noktada, kameranın etkin yapılandırmasını tanımlamadınız. Oturum yapılandırıldığında, yakalamayı oluşturup gönderebilirsiniz. talep ediyorum.
Tamponlara yazılırken girdilere uygulanan dönüşüm
her bir hedefin türüne göre belirlenir. Hedef,
Surface
. Android yapısı,
etkin yapılandırmadaki ham bir resmi, şuna uygun bir biçime dönüştürür:
her bir hedefe bakın. Dönüşüm, Floodlight etiketindeki piksel biçimi ve boyutu ile kontrol edilir.
belirli Surface
.
Çerçeve en iyisini yapmaya çalışsa da biraz Surface
yapılandırma kombinasyonları çalışmayabilir ve bu da oturum veya deneme
bir istek gönderirken çalışma zamanı hatası verebilir veya
düşmesine neden olabilir. Bu çerçeve, belli bir ekip üyesiyle
cihaz, yüzey ve istek parametrelerinin birleşiminden oluşmuyor. Dokümanlar
createCaptureSession()
daha fazla bilgi sağlar.
Tek Yakalama İstekleri
Her kare için kullanılan yapılandırma CaptureRequest
ile kodlanır. Bu da
gönderilir. Bir yakalama isteği oluşturmak için şunlardan birini kullanabilirsiniz:
önceden tanımlanmış
şablonlar
veya tam kontrol için TEMPLATE_MANUAL
kullanabilirsiniz. Bir
üzerinde kullanılacak bir veya daha fazla çıktı arabelleği sağlamanız
talep ediyor. Yalnızca yakalamada önceden tanımlanmış arabellekleri kullanabilirsiniz
oturum açın.
Yakalama istekleri bir
geliştirici kalıbı
ve geliştiricilere, farklı birçok farklı etiket
diğer seçenekler de dahildir:
otomatik pozlama
otomatik odaklama,
ve
lens diyafram açıklığı.
Bir alanı ayarlamadan önce, ilgili seçeneğin
telefon ederek cihaz
CameraCharacteristics.getAvailableCaptureRequestKeys()
ve istenen değerin uygun kamera kontrol edilerek desteklendiğinden emin olun.
bir diğer özellik, mevcut otomatik pozlama
modları.
Şablonu kullanarak SurfaceView
için yakalama isteği oluşturmak istiyorsanız
herhangi bir değişiklik yapılmadan önizleme için tasarlandığından,
CameraDevice.TEMPLATE_PREVIEW
:
Kotlin
val session: CameraCaptureSession = ... // from CameraCaptureSession.StateCallback val captureRequest = session.device.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW) captureRequest.addTarget(previewSurface)
Java
CameraCaptureSession session = ...; // from CameraCaptureSession.StateCallback CaptureRequest.Builder captureRequest = session.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); captureRequest.addTarget(previewSurface);
Tanımlanmış bir yakalama isteği ile artık görev bunu kamera oturumuna iletebiliriz:
Kotlin
val session: CameraCaptureSession = ... // from CameraCaptureSession.StateCallback val captureRequest: CaptureRequest = ... // from CameraDevice.createCaptureRequest() // The first null argument corresponds to the capture callback, which you // provide if you want to retrieve frame metadata or keep track of failed capture // requests that can indicate dropped frames; the second null argument // corresponds to the Handler used by the asynchronous callback, which falls // back to the current thread's looper if null session.capture(captureRequest.build(), null, null)
Java
CameraCaptureSession session = ...; // from CameraCaptureSession.StateCallback CaptureRequest captureRequest = ...; // from CameraDevice.createCaptureRequest() // The first null argument corresponds to the capture callback, which you // provide if you want to retrieve frame metadata or keep track of failed // capture // requests that can indicate dropped frames; the second null argument // corresponds to the Handler used by the asynchronous callback, which falls // back to the current thread's looper if null session.capture(captureRequest.build(), null, null);
Belirli bir arabelleğe bir çıkış çerçevesi konulduğunda yakalama
geri arama
tetiklenir. Birçok durumda,
ImageReader.OnImageAvailableListener
değeri, içerdiği kare işlendiğinde tetiklenir. Saat:
bu noktada resim verilerini belirtilen arabelleğin dışına alabilirsiniz.
Tekrar Yakalama İstekleri
Tek kamera istekleri yapmak kolaydır, ancak canlı bir görüntü göstermek için önizleme veya video eklemek çok kullanışlı değildir. Bu durumda, sürekli bir akış şeklinde çalışır. Aşağıdaki kod snippet'i nasıl eklendiğini gösterir yinelenen istek ekleyin:
Kotlin
val session: CameraCaptureSession = ... // from CameraCaptureSession.StateCallback val captureRequest: CaptureRequest = ... // from CameraDevice.createCaptureRequest() // This keeps sending the capture request as frequently as possible until // the // session is torn down or session.stopRepeating() is called // session.setRepeatingRequest(captureRequest.build(), null, null)
Java
CameraCaptureSession session = ...; // from CameraCaptureSession.StateCallback CaptureRequest captureRequest = ...; // from CameraDevice.createCaptureRequest() // This keeps sending the capture request as frequently as possible until the // session is torn down or session.stopRepeating() is called // session.setRepeatingRequest(captureRequest.build(), null, null);
Tekrarlanan çekim isteği, kamera cihazının sürekli olarak fotoğraf çekmesine neden oluyor
CaptureRequest
içindeki ayarları kullanarak resimler. Camera2 API'si
Ayrıca, kullanıcıların fotoğraf veya video yükleyerek kameradan video
CaptureRequests
burada görüldüğü gibi tekrarlanıyor
Kamera2 örneği
kod deposunu ziyaret edin. Ayrıca, yüksek kaliteli ve yüksek çözünürlüklü
yinelenen seri çekimin kullanıldığı yüksek hızlı (yavaş çekim) video CaptureRequests
Kamera2 ağır çekim video örnek uygulamasında gösterildiği gibi
bulabilirsiniz.
Aralıklı Yakalama İstekleri
Tekrarlanan yakalama isteği etkinken ikinci bir yakalama isteği göndermek için Örneğin, vizör görüntüleyerek kullanıcıların fotoğraf çekmesini sağlayabilirsiniz. Bunu yapmak için devam eden isteği durdurmanızı sağlar. Bunun yerine, tekrarlanmayan bir yakalama yayınlarsınız. isteği gönderir.
Kullanılan çıkış arabelleğinin, kamera oturumunun bir parçası olarak yapılandırılması gerekir oturum ilk oluşturulduğunda. Tekrarlanan isteklerin önceliği, aşağıdaki örneğin çalışmasını sağlayan tek kare veya seri çekim istekleri:
Kotlin
val session: CameraCaptureSession = ... // from CameraCaptureSession.StateCallback // Create the repeating request and dispatch it val repeatingRequest = session.device.createCaptureRequest( CameraDevice.TEMPLATE_PREVIEW) repeatingRequest.addTarget(previewSurface) session.setRepeatingRequest(repeatingRequest.build(), null, null) // Some time later... // Create the single request and dispatch it // NOTE: This can disrupt the ongoing repeating request momentarily val singleRequest = session.device.createCaptureRequest( CameraDevice.TEMPLATE_STILL_CAPTURE) singleRequest.addTarget(imReaderSurface) session.capture(singleRequest.build(), null, null)
Java
CameraCaptureSession session = ...; // from CameraCaptureSession.StateCallback // Create the repeating request and dispatch it CaptureRequest.Builder repeatingRequest = session.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); repeatingRequest.addTarget(previewSurface); session.setRepeatingRequest(repeatingRequest.build(), null, null); // Some time later... // Create the single request and dispatch it // NOTE: This can disrupt the ongoing repeating request momentarily CaptureRequest.Builder singleRequest = session.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); singleRequest.addTarget(imReaderSurface); session.capture(singleRequest.build(), null, null);
Ancak bu yaklaşımın dezavantajı vardır: Tam olarak ne zaman tek istek gerçekleşir. Aşağıdaki şekilde A tekrarlanıyorsa yakalama isteğini gösterir ve B tek kare yakalama isteğidir. oturum, istek sırasını işler:
Gelen son yinelenen istek arasındaki gecikmeyle ilgili bir garanti verilmez. B isteği etkinleştirilmeden önce A ve A tekrar kullanıldığında olduğundan bazı kareler atlanır. Paydaşlarla toplantı yaparken ne gerek var?
B isteğinde bulunmak için A isteğindeki çıkış hedeflerini ekleyin. Bu şekilde, B'nin çerçevesi hazırdır. Bu çerçeve, A'nın çıkış hedeflerine kopyalanır. Örneğin, her bir görüntüden en iyi şekilde yararlanmaya devam etmek için sabit bir kare hızına sahip olmalıdır. Önceki kodda İsteği oluşturmadan önce
singleRequest.addTarget(previewSurface)
.Bu özel senaryoda kullanılmak üzere tasarlanmış şablonların bir kombinasyonunu kullanın. gecikmeleri devre dışı bırakabilirsiniz.