Android Camera2 – Camera2 API:n käyttäminen valokuvien ja videoiden ottamiseen (2023)

/ #Android
Android Camera2 – Camera2 API:n käyttäminen valokuvien ja videoiden ottamiseen (1)
Tomer Ben Rachel
Android Camera2 – Camera2 API:n käyttäminen valokuvien ja videoiden ottamiseen (2)

Me kaikki käytämme kameraa puhelimissamme ja käytämme sitä l-o-t. Jotkut sovellukset ovat jopa integroineet kameran ominaisuutena.

Toisessa päässä on tavallinen tapa olla vuorovaikutuksessa kameran kanssa. Toisaalta on tapa mukauttaa vuorovaikutustasi kameran kanssa. Tämä ero on tärkeä tehdä. Ja tässä Camera2 tulee mukaan.

Mikä on Camera2?

Vaikka se on ollut saatavilla API-tasosta 21 lähtien, Camera2 API:n on oltava yksi monimutkaisimmista arkkitehtuurikehittäjien osista.

Tämä API ja sen edeltäjä otettiin käyttöön, jotta kehittäjät voivat hyödyntää sovellustensa sisällä olevan kameran vuorovaikutuksen voimaa.

Samoin kuin on tapa olla vuorovaikutuksessa mikrofonin tai laitteen äänenvoimakkuuden kanssa, Camera2 API tarjoaa työkalut vuorovaikutukseen laitteen kameran kanssa.

Yleisesti ottaen, jos haluat käyttää Camera2 API:ta, se olisi todennäköisesti muutakin kuin vain kuvan ottamista tai videon tallentamista. Tämä johtuu siitä, että API antaa sinun hallita kameraa perusteellisesti paljastamalla erilaisia ​​luokkia, jotka on määritettävä tietylle laitteelle.

Vaikka oletkin käsitellyt kameraa aiemmin, se on niin raju muutos entiseen kameran API:hen, että saatat yhtä hyvin unohtaa kaiken, mitä tiedät.

Siellä on paljon resursseja, jotka yrittävät esitellä tämän API:n käyttöä suoraan, mutta jotkut niistä voivat olla vanhentuneita ja jotkut eivät anna koko kuvaa.

Joten sen sijaan, että yrittäisit täyttää puuttuvat kohdat itse, tämä artikkeli on (toivottavasti) sinun keskitetysti vuorovaikutuksessa Camera2 API:n kanssa.

Camera2 käyttökotelot

Ennen kuin sukeltaamme mihinkään, on tärkeää ymmärtää, että jos haluat käyttää kameraa vain kuvan ottamiseen tai videon tallentamiseen, sinun ei tarvitse vaivautua Camera2 API:n kanssa.

Ensisijainen syy Camera2 API:n käyttöön on, jos sovelluksesi vaatii mukautettua vuorovaikutusta kameran tai sen toimintojen kanssa.

Jos olet kiinnostunut tekemään edellisen jälkimmäisen sijaan, suosittelen, että tutustut seuraavaan Googlen dokumentaatioon:

  1. Ota valokuvia
  2. Kaappaa video

Sieltä löydät kaikki tarvittavat vaiheet, jotka sinun on suoritettava upeiden valokuvien ja videoiden tallentamiseen kamerallasi. Mutta tässä artikkelissa pääpaino on Camera2:n käytössä.

Nyt on joitain asioita, jotka meidän on lisättävä luettelotiedostoomme:

Kameran käyttöoikeudet:

Kameran ominaisuus:

Sinun on tarkistettava, onko kameralupa myönnetty vai ei, mutta koska tätä aihetta on käsitelty laajasti, emme käsittele sitä tässä artikkelissa.

Camera2 API -komponenttien määrittäminen

Camera2 API tuo useita uusia käyttöliittymiä ja luokkia. Erotetaan jokainen niistä, jotta ymmärrämme paremmin, kuinka niitä käytetään.

(Video) NYC High Line & Hudson River Walk - 4K with Captions

Android Camera2 – Camera2 API:n käyttäminen valokuvien ja videoiden ottamiseen (3)

Ensinnäkin aloitammeTextureView.

Camera2 TextureView -komponentti

TextureView on käyttöliittymäkomponentti, jota käytät sisältövirran näyttämiseen (ajattele videota). Meidän on käytettävä TextureView'ta näyttääksemme syötteen kamerasta, olipa kyseessä esikatselu tai ennen kuvan/videon ottamista.

Kaksi ominaisuutta, joita on tärkeää käyttää TextureView'n suhteen, ovat:

  • Pintateksti-kenttä
  • SurfaceTextureListener-käyttöliittymä

Ensimmäinen on paikka, jossa sisältö näytetään, ja toisessa on neljä takaisinsoittoa:

  1. onSurfaceTextureAvailable
  2. onSurfaceTextureSizeChanged
  3. onSurfaceTextureUpdated
  4. onSurfaceTextureDestroyed
private val surfaceTextureListener = objekti : TextureView.SurfaceTextureListener { override fun onSurfaceTextureAvailable(tekstuuri: SurfaceTexture, leveys: Int, korkeus: Int) { } ohita hauska onSurfaceTextureSizeChanged(tekstuuri: Pintatekstuuri, leveys: Inttrodeteksti) tekstuuri: SurfaceTexture) { } override fun onSurfaceTextureUpdated(tekstuuri: SurfaceTexture) { }}

Ensimmäinen takaisinsoitto on erittäin tärkeä kameraa käytettäessä. Tämä johtuu siitä, että haluamme saada ilmoituksen, kun SurfaceTexture on saatavilla, jotta voimme alkaa näyttää syötettä siinä.

Huomaa, että vasta kun TextureView on liitetty ikkunaan, se tulee saataville.

Vuorovaikutus kameran kanssa on muuttunut edellisen API:n jälkeen. Nyt meillä onKameranhallinta. Tämä on järjestelmäpalvelu, jonka avulla voimme olla vuorovaikutuksessaKameralaiteesineitä.

Menetelmät, joihin haluat kiinnittää erityistä huomiota, ovat:

Kun tiedämme, että TextureView on saatavilla ja valmis, meidän on soitettava openCameralle avataksemme yhteyden kameraan. Tämä menetelmä sisältää kolme argumenttia:

  1. Kameratunnus – merkkijono
  2. CameraDevice.StateCallback
  3. Käsittelijä

CameraId-argumentti ilmaisee, mihin kameraan haluamme muodostaa yhteyden. Puhelimessasi on pääasiassa kaksi kameraa, etu- ja takakamera. Jokaisella on oma yksilöllinen tunnus. Yleensä se on joko nolla tai ykkönen.

Miten saamme kameran tunnuksen? Käytämme CameraManagerin getCamerasIdList-menetelmää. Se palauttaa merkkijonotyypin kaikista laitteesta tunnistetuista kameratunnuksista.

val cameraManager: CameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManagerval cameraIds: Array = cameraManager.cameraIdListvar cameraId: String = ""for (id in cameraIds) { val cameraCharacteristics = cameraManager.getCamera(we wantCharacteristics) valitaksesi takakameran etukameran sijaan if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) jatka } val previewSize = cameraCharacteristics.get(CameraCharacteristics.get(CameraCharacteristics)!! izes(ImageFormat.JPEG) .maxByOrNull { it.height * it.width }!! val imageReader = ImageReader.newInstance(previewSize.width, previewSize.height, ImageFormat.JPEG, 1) imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler) cameraId = id}

Seuraavat argumentit ovat takaisinkutsuja kameran tilaan, kun yritämme avata sen. Jos ajattelet sitä, tällä toiminnolla voi olla vain useita tuloksia:

  • Kamera avautuu onnistuneesti
  • Kamera katkeaa
  • Jokin virhe tapahtuu

Ja se on mitä löydät CameraDevice.StateCallbackin sisältä:

yksityinen val cameraStateCallback = objekti : CameraDevice.StateCallback() { override fun onOpened(camera: CameraDevice) { } override fun onDisconnected(cameraDevice: CameraDevice) { } override fun onError(cameraDevice: CameraDevice, error: Int) { when val(Ms) virhe) { ERROR_CAMERA_DEVICE -> "Fatal (laite)" ERROR_CAMERA_DISABLED -> "Laitekäytäntö" ERROR_CAMERA_IN_USE -> "Kamera käytössä" ERROR_CAMERA_SERVICE -> "Kuolemallinen (palvelu)" ERROR_MAX_CAMERAS_INxUSE m ->kamerat "Unknown other" -> " } Log.e(TAG, "Virhe yritettäessä yhdistää kameraa $errorMsg") } }

Kolmas argumentti koskee sitä, missä tämä työ tapahtuu. Koska emme halua miehittää pääsäiettä, on parempi tehdä tämä työ taustalla.

Siksi meidän on välitettävä käsittelijä sille. Olisi viisasta, että tämä käsittelijäinstanssi instantoidaan valitsemallamme säikeellä, jotta voimme delegoida sille työtä.

yksityinen lateinit var backgroundHandlerThread: KäsittelijäThreadprivate lateinit var backgroundHandler: Käsittelijä yksityinen hauska aloitusBackgroundThread() { backgroundHandlerThread = HandlerThread("CameraVideoThread") backgroundHandlerThread.start() backgroundHandler = OperaattoriThread. { backgroundHandlerThread.quitSafely() backgroundHandlerThread.join()}

Kaiken, mitä olemme tehneet, voimme nyt kutsua openCameraksi:

cameraManager.openCamera(cameraId, cameraStateCallback,backgroundHandler)

Sitten sisälläonOpened takaisinsoitto, voimme alkaa käsitellä logiikkaa, miten kameran syöte esitetään käyttäjälle TextureView-sovelluksen kautta.

Android Camera2 – Camera2 API:n käyttäminen valokuvien ja videoiden ottamiseen (4)

Kuinka näyttää syötteen esikatselu

Meillä on kameramme (cameraDevice) ja TextureView, jotka näyttävät syötteen. Mutta meidän on yhdistettävä ne toisiinsa, jotta voimme näyttää syötteen esikatselun.

Tätä varten käytämme TextureView:n SurfaceTexture-ominaisuutta ja rakennamme CaptureRequestin.

val surfaceTexture : Pintatekstuuri? = textureView.surfaceTexture // 1val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId) //2val previewSize = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)!! .getOutputSizes (imageFormat.jpeg) .Maxbyornull {it.height * it.width} !! SurfaceTexture? .setDefaultBuffersize (esikatselusta. CameraDevice.TEMPLATE_PREVIEW) //4captureRequestBuilder.addTarget(previewSurface) //5cameraDevice.createCaptureSession(listOf(previewSurface, imageReader.surface), captureStateCallback, null) //6

Yllä olevassa koodissa saamme ensin pintatekstuurin TextureView-näkymästämme. Sitten käytämme cameraCharacteristics-objektia saadaksemme luettelon kaikista lähtökooista. Halutun koon saamiseksi asetamme sen pintatekstuurille.

Seuraavaksi luomme captureRequest-pyynnön, johon siirrymmeTEMPLATE_PREVIEW. Lisäämme syöttöpinnamme captureRequestiin.

(Video) Sydney, Australia Walking Tour - 4K60fps with Captions - Prowalk Tours

Lopuksi aloitamme captureSessionin syöttö- ja lähtöpinnoillamme, captureStateCallback ja annamme käsittelijälle nollan.

Joten mikä tämä captureStateCallback on? Jos muistat kaavion tämän artikkelin alusta, se on osa CameraCaptureSession-ohjelmaa, jonka aloitamme. Tämä objekti seuraa captureRequestin edistymistä seuraavilla takaisinkutsuilla:

  • onConfigured
  • onConfigureFailed
yksityinen val captureStateCallback = objekti : CameraCaptureSession.StateCallback() { override fun onConfigureFailed(session: CameraCaptureSession) { } override fun onConfigured(session: CameraCaptureSession) { }}

KuncameraCaptureSessionon määritetty onnistuneesti, asetimme istunnolle toistuvan pyynnön, jotta voimme näyttää esikatselun jatkuvasti.

Tätä varten käytämme takaisinkutsussa saatua istuntoobjektia:

session.setRepeatingRequest(captureRequestBuilder.build(), null, backgroundHandler)

Tunnistat aiemmin luomamme captureRequestBuilder-objektin ensimmäisenä argumenttina tälle menetelmälle. Otamme käyttöön koontimenetelmän, joten viimeinen välitetty parametri on CaptureRequest.

Toinen argumentti on CameraCaptureSession.captureCallback-kuuntelija, mutta koska emme halua tehdä mitään kaapatuilla kuvilla (koska tämä on esikatselu), välitämme tyhjän.

Kolmas argumentti on käsittelijä, ja tässä käytämme omaa taustakäsittelijäämme. Tästä syystä jätimme edellisessä osiossa tyhjäksi, koska toistuva pyyntö suoritetaan taustasäikeessä.

Android Camera2 – Camera2 API:n käyttäminen valokuvien ja videoiden ottamiseen (5)

Kuinka ottaa kuva

Kameran live-esikatselu on mahtavaa, mutta useimmat käyttäjät haluavat todennäköisesti tehdä sen kanssa jotain. Osa logiikasta, jonka kirjoitamme ottaaksesi kuvan, on samanlainen kuin mitä teimme edellisessä osiossa.

  1. Luomme sieppauspyynnön
  2. Käytämme ImageReaderia ja sen kuuntelijaa otetun kuvan keräämiseen
  3. Käytämme cameraCaptureSession-ohjelmaamme kaappausmenetelmän
val orientations : SparseIntArray = SparseIntArray(4).apply { append(Surface.ROTATION_0, 0) append(Surface.ROTATION_90, 90) append(Surface.ROTATION_180, 180) append(Surface.ROTATION_270)} createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)captureRequestBuilder.addTarget(imageReader.surface)val rotation = windowManager.defaultDisplay.rotationcaptureRequestBuilder.set(CaptureRequest.JPEG-rootationS(CaptureRequest.JPEGapture.sactures_ORIENTATION) aptureRequestBuilder.build(), captureCallback, null)

Mutta mikä tämä onImageReader? No, ImageReader tarjoaa pääsyn kuvatietoihin, jotka renderöidään pinnalle. Meidän tapauksessamme se on TextureView'n pinta.

Jos katsot koodinpätkää edellisestä osiosta, huomaat, että olemme jo määrittäneet ImageReaderin sinne.

val cameraManager: CameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManagerval cameraIds: Array = cameraManager.cameraIdListvar cameraId: String = ""for (id in cameraIds) { val cameraCharacteristics = cameraManager.getCameraf(we wantCharacteristics jos haluat valita takakameran etukameran sijaan if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) jatka } val previewSize = cameraCharacteristics.get(CameraCharacteristics.get(CameraCharacteristics)!! izes(ImageFormat.JPEG) .maxByOrNull { it.height * it.width }!! val imageReader = ImageReader.newInstance(previewSize.width, previewSize.height, ImageFormat.JPEG, 1) imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler) cameraId = id}

Kuten yllä näet, instantoimme ImageReaderin antamalla leveyden ja korkeuden, kuvamuodon, jossa haluamme kuvamme olevan, ja kuvien määrän, jonka se voi ottaa.

ImageReader-luokan ominaisuus on kuuntelija nimeltä onImageAvailableListener. Tämä kuuntelija käynnistyy, kun valokuva on otettu (koska menimme sen pintaan sieppauspyyntömme lähtölähteenä).

val onImageAvailableListener = objekti: ImageReader.OnImageAvailableListener{ ohittaa hauska onImageAvailable(lukija: ImageReader) { val image: Image = reader.acquireLatestImage() } }

⚠️Muista sulkea kuva käsittelyn jälkeen, muuten et voi ottaa toista kuvaa.

Android Camera2 – Camera2 API:n käyttäminen valokuvien ja videoiden ottamiseen (6)

Kuinka tallentaa video

Videon tallentamiseksi meidän on oltava vuorovaikutuksessa uuden kohteen kanssaMediaRecorder. Mediatallennusobjekti vastaa äänen ja videon tallentamisesta, ja käytämme sitä juuri niin.

Ennen kuin teemme mitään, meidän on määritettävä mediatallennin. On olemassa erilaisia ​​kokoonpanoja käsitellä janiiden on oltava oikeassa järjestyksessä tai muuten poikkeuksia heitetään.

Alla on esimerkki valikoimasta kokoonpanoja, joiden avulla voimme kaapata videota (ilman ääntä).

fun setupMediaRecorder(leveys: Int, korkeus: Int) { val mediaRecorder: MediaRecorder = MediaRecorder() mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE) mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) MediaRecorder.OutputFormat.MPEG_4) MediaRecorder.OutputFormat.MPEG_4) MediaRecorder. 64) mediaRecorder.setVideoSize(videoSize.width, videoSize.height) mediaRecorder.setVideoFrameRate(30) mediaRecorder.setOutputFile(PATH_TO_FILE) mediaRecorder.setVideoEncodingBitRate(10_000_000) mediarecorder()}.

Kiinnitä huomiotasetOutputFilemenetelmää, koska se odottaa polun tiedostoon, joka tallentaa videomme. Kaikkien näiden asetusten määrittämisen lopussa meidän on kutsuttava valmistelu.

Huomaa, että mediaRecorderilla on myös käynnistysmenetelmä ja meidän on kutsuttava valmistelu ennen kutsumista.

MediaRecoderin asennuksen jälkeen meidän on luotava sieppauspyyntö ja sieppausistunto.

fun startRecording() { val surfaceTexture : SurfaceTexture? = textureView.surfaceTexture surfaceTexture?.setDefaultBufferSize(previewSize.width, previewSize.height) val previewSurface: Pinta = Pinta(pintatekstuuri) val recordingSurface = mediaRecorder.surface captureRequestBuilder = cameraDevice.createCaptureCapture_DeviceRequest(CORDuCapture_DeviceRequest. dTarget(previewSurface) captureRequestBuilder. addTarget(recordingSurface) cameraDevice.createCaptureSession(listOf(previewSurface, recordingSurface), captureStateVideoCallback, backgroundHandler) }

Samoin kuin esikatselun asettaminen tai valokuvan ottaminen, meidän on määritettävä syöttö- ja tulostuspinnamme.

Tässä luomme pintaobjektin TextureView:n pintatekstuurista ja otamme pinnan myös mediatallentimesta. Kuljemme sisäänTEMPLATE_RECORDarvoa sieppauspyyntöä luotaessa.

(Video) Bondi to Coogee Coastal Walk - Sydney, Australia - 4K60fps - 6 Miles!

CaptureStateVideoCallback on samaa tyyppiä, jota käytimme still-kuvassa, mutta onConfigured-soittopyynnön sisällä kutsumme mediatallentimen käynnistysmenetelmää.

val captureStateVideoCallback = objekti : CameraCaptureSession.StateCallback() { override fun onConfigureFailed(session: CameraCaptureSession) { } override fun onConfigured(session: CameraCaptureSession) { session.setRepeatingRequest(CaptureRequest) mediaRecorder.start() } }

Nyt nauhoitamme videota, mutta kuinka lopetamme nauhoituksen? Tätä varten käytämme mediaRecorder-objektin pysäytys- ja palautusmenetelmiä:

mediaRecorder.stop()mediaRecorder.reset()

Johtopäätös

Siinä oli paljon käsiteltävää. Joten jos pääsit tänne, onnittelut! Sitä ei voi kiertää – vain likaamalla kätesi koodilla alat ymmärtää, kuinka kaikki liittyy toisiinsa.

Sinua rohkaistaan ​​tutustumaan kaikkiin tähän artikkeliin alla olevaan koodiin:

MediumArticles/Camrea2API at master · TomerPacific/MediumArticles

Arkisto, joka sisältää useisiin kirjoittamiini Medium-artikkeleihin liittyvää koodia - MediumArticles/Camrea2API isännässä · TomerPacific/MediumArticles

Android Camera2 – Camera2 API:n käyttäminen valokuvien ja videoiden ottamiseen (7)TomerPacificGitHub

Android Camera2 – Camera2 API:n käyttäminen valokuvien ja videoiden ottamiseen (8)

Muista, että tämä on vain jäävuoren huippu Camera2 API:n suhteen. Voit tehdä monia muita asioita, kuten hidastettua videota, vaihtaa etu- ja takakameran välillä, ohjata tarkennusta ja paljon muuta.

MAINOS

MAINOS

MAINOS

MAINOS

MAINOS

(Video) SCP-610 Flesh että Hates (kaikki asiakirjat ja Lokit)

MAINOS

MAINOS

MAINOS

MAINOS

MAINOS

MAINOS

MAINOS

Android Camera2 – Camera2 API:n käyttäminen valokuvien ja videoiden ottamiseen (9)
Tomer Ben Rachel

Lukealisää postauksia.

Jos tästä artikkelista oli apua, .

Opi koodaamaan ilmaiseksi. freeCodeCampin avoimen lähdekoodin opetussuunnitelma on auttanut yli 40 000 ihmistä saamaan töitä kehittäjänä.Aloittaa

MAINOS

(Video) Hallituskriisi ja vihaajien ongelma – kasvatetaan yhdessä youtubessa 6.8.2022 san ten chan

FAQs

What is the use of camera API in Android? ›

This package is the primary API for controlling device cameras. It can be used to take pictures or videos when you are building a camera application.

How to enable Camera2API module in Android? ›

How to Enable Camera2API
  1. Open terminal emulator app.
  2. Type su and enter. Give root permissions.
  3. Type setprop persist.camera.HAL3.enabled 1 and enter.
  4. Type setprop vendor.persist.camera.HAL3.enabled 1 and enter.
  5. Reboot your phone.

What is Camera2API Android? ›

Camera2 is the low-level Android camera package that replaces the deprecated Camera class. Camera2 provides in-depth controls for complex use cases, but requires you to manage device-specific configurations. For more information, see the Camera2 reference documentation.

References

Top Articles
Latest Posts
Article information

Author: Corie Satterfield

Last Updated: 07/09/2023

Views: 6066

Rating: 4.1 / 5 (42 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Corie Satterfield

Birthday: 1992-08-19

Address: 850 Benjamin Bridge, Dickinsonchester, CO 68572-0542

Phone: +26813599986666

Job: Sales Manager

Hobby: Table tennis, Soapmaking, Flower arranging, amateur radio, Rock climbing, scrapbook, Horseback riding

Introduction: My name is Corie Satterfield, I am a fancy, perfect, spotless, quaint, fantastic, funny, lucky person who loves writing and wants to share my knowledge and understanding with you.