Begrepet Augmented Reality (AR) har mottatt en begrunnelse av interesse de siste årene, da iPhone og andre mobile enheter har plassert stadig flere kraftige prosessorer, sensorer og kameraer i hendene på millioner av mennesker over hele verden. For første gang siden begrepet ble laget på 1990-tallet, kan gjennomsnittsforbrukeren nå peer gjennom skjermen på smarttelefonen og finne et lag av virkelighet de aldri visste eksisterte. Denne Mobiletuts + premium serien vil vike inn i verden av både Augmented Reality og Mixed Reality. Det vil demonstrere, trinnvis, hvordan du kan slå sammen iPhone-kameraet og sensorer med datagrafikk for å lage en forbedret, endret eller forvrengt versjon av verden rundt deg.
Hovedvekten i denne opplæringsserien handler om å forstå komponentene som er tilgjengelige på iPhone, som muliggjør erfaringer med Augmented Reality og Mixed Reality. Dette oppnås ved å lage en enkel AR-demo, og denne opplæringen vil starte oss på den banen ved å takle den mest grunnleggende oppgaven i mange AR-apper: å få programmatisk tilgang til enhetsvideoen.
Begynn med å lansere Xcode og opprette et nytt prosjekt. Velg "Vis-basert program" som maletype og klikk "Neste":
På neste skjermbilde skriver du inn "MobiletutsAR" som Produktnavn.
For Bedriftsidentifikator feltet, har jeg brukt "com.mobiletuts.ardemo", men du må oppgi den unike identifikatoren som samsvarer med din egen utvikler- eller Ad Hoc Distribution-provisjonsprofil.
Prosessen med å sette opp en enhet for applikasjonstest er utenfor omfanget av denne opplæringen, men dokumentasjon på denne prosessen er tilgjengelig fra følgende kilder:
Som nevnt ovenfor må du være medlem av det betalte iOS-utviklerprogrammet for å teste applikasjoner på fysiske iOS-enheter.
Velg "iPhone" for Enhetsfamilie fall ned. Selv om denne opplæringen vil fokusere på å bygge en enkel AR-applikasjon for iPhone, vil de viste prinsippene gjelde for en hvilken som helst annen iOS-enhet med nødvendig maskinvare.
Fjern merket for "Inkluder enhetstester" -boksen, og klikk deretter "Neste". Enhetstesting er unødvendig for dette AR-demo-prosjektet, men kan være en stor hjelp i den virkelige livscyklusen for programvareutvikling (offisiell Apple-dokumentasjon om enhetstesting).
Det siste trinnet i denne prosessen er å velge hvor du vil lagre prosjektet på harddisken din og klikke på "Opprett".
For å begynne å jobbe med kameradata og fullføre denne opplæringen, skal vi ha AVFoundation-rammeverket. AVFoundation-rammeverket gir den nødvendige funksjonaliteten for å ta bilder fra enhetskameraet, som er hovedfokus for denne opplæringen. Det gir også metoder for å opprette, administrere og avspille andre medieressurser.
For mer detaljert informasjon, se Apples offisielle AVFoundation Reference og programmeringsveiledning.
Prosessen med å importere et rammeverk til et Xcode 4-prosjekt er rett og trolig godt forstått, men for de som er nye til Xcode 4, vil det bli demonstrert likevel.
Velg "ARDemo" -prosjektet i Xcode 4 Project Navigator. Deretter klikker du på "ARDemo" målet og klikker deretter på "Bygg faser" -fanen før du utvider rullegardinmenyen "Link binær med biblioteker"..
Klikk på "+" -symbolet og velg "AVFoundation.framework" -verdien fra listen. Klikk på "Legg til".
Etter at rammen er lagt til og vises i Xcode Project Navigator, drar du den inn i mappen "Rammer" for å holde prosjektet ordnet.
Gjenta denne prosessen for å legge til både "CoreMedia.framework" og "CoreVideo.framework".
Nå som vi har de ovennevnte rammene i prosjektet, må vi gjøre dem tilgjengelige for vår kode. Åpen ARDemoViewController.h
og legg til følgende linje:
#importere
For denne leksjonen skal vi deklarere to data medlemmer og en metode i ARDemoViewController.h
fil:
@interface ARDemoViewController: UIViewController AVCaptureSession * cameraCaptureSession; AVCaptureVideoPreviewLayer * kameraPreviewLayer; - (void) initializeCaptureSession; @slutt
På linje 3, en forekomst av AVCaptureSession
er erklært. De AVCaptureSession
klassen er kjernekomponenten som brukes til å administrere videoinngang mottatt fra enhetskameraet. I tillegg til å administrere kamerainngangen, tilbyr klassen også delegerte metoder som gjør hver ramme tilgjengelig for søknaden din for tilpasset behandling. Av denne grunn liker jeg å tenke på det som en "pipeline".
På linje 4, en forekomst av AVCaptureVideoPreviewLayer
er erklært. Dette er en spesiell underklasse av CALayer
designet for å jobbe med en AVCaptureSession
ved å vise videoutgangen som er streamet fra kameraet.
På linje 7 på -(Void) initializeCaptureSession
Metoden er erklært. Denne metoden vil initialisere cameraCaptureSession
, link cameraPreviewLayer
med cameraCaptureSession
, og legg til cameraCaptureSession
til utsikten.
Resten av denne opplæringen vil fokusere på -initializeCaptureSession
metode declard i trinn 3. Denne metoden skal kalles fra -viewDidLoad
fordi vi vil at enhetskameraet umiddelbart begynner å streame når applikasjonen laster. La oss gå videre og sette opp dette:
- (void) viewDidLoad [super viewDidLoad]; [self initializeCaptureSession]; - (void) initializeCaptureSession
Hvis du har gjort mye arbeid med kameraet i UIKit
, du er sikkert allerede kjent med UIImagePickerController
klassemetode +availableMediaTypesForSourceType:
som returnerer en NSArray
av tilgjengelige kildetyper. Du kan deretter iterere over den returnerte gruppen og ser etter ønsket kilde type for å avgjøre hvorvidt enheten kan ta video eller ikke.
De Foundation-
rammeverket gir lignende funksjonalitet for å finne tilgjengelige kilder til inngang (kalt "opptaksenheter").
// Forsøk å initialisere AVCaptureDevice med tilbake kamera NSArray * videoDevices = [AVCaptureDevice devicesWithMediaType: AVMediaTypeVideo]; AVCaptureDevice * captureDevice = null; for (AVCaptureDevice * -enhet i videoDevices) if (device.position == AVCaptureDevicePositionBack) captureDevice = device; gå i stykker; // Hvis kameraet er tilgjengelig ved opptakssesjon dersom (captureDevice) // Ønsket AVCaptureDevice er tilgjengelig annet // Ønsket AVCaptureDevice er ikke tilgjengelig. Aler brukeren og kausjonen. UIAlertView * alert = [[UIAlertView tildeling] initWithTitle: @ "Kamera ikke tilgjengelig" melding: @ "" delegat: null annullerButtonTitle: @ "Okay" otherButtonTitles: null]; [varslingsutstilling]; [våken utgivelse];
På linje 2 opprettes en rekke av alle tilgjengelige opptaksenheter som kan streame video. På linjene 4 - 11 blir det spredt i et forsøk på å finne en enhet med posisjonsverdien AVCaptureDevicePositionBack
(Hvis du vil hellere fullføre denne opplæringen med kameraet som vender fremover, kan du i stedet søke etter AVCaptureDevicePositionFront
).
Resten av koden ovenfor oppretter bare en betinget test captureDevice
for å tillate oss å reagere dynamisk dersom den ønskede enheten ikke er tilgjengelig, uansett grunn.
Etter å ha sørget for at ønsket inngangsenhet faktisk er tilgjengelig, la oss gå videre og sette opp videoopptakssesjonen vår:
// Hvis kameraet er tilgjengelig ved opptakssesjonen hvis (captureDevice) // Allokere kameraopptakssesjon cameraCaptureSession = [[AVCaptureSession alloc] init]; cameraCaptureSession.sessionPreset = AVCaptureSessionPresetMedium; // Konfigurer innspillingssessinginngang AVCaptureDeviceInput * videoIn = [AVCaptureDeviceInput deviceInputWithDevice: captureDevice error: null]; [kameraCaptureSession addInput: videoIn]; // Konfigurer innspillingsøksutgang AVCaptureVideoDataOutput * videoOut = [[AVCaptureVideoDataOutput alloc] init]; [videoOut setAlwaysDiscardsLateVideoFrames: YES]; [cameraCaptureSession addOutput: videoOut]; [videoOut release];
På linje 6, cameraCaptureSession
er tildelt (dette vil bli utgitt senere).
På linje 7 angir vi at kvaliteten på videoutgangen som genereres fra denne opptakssesjonen, skal være AVCaptureSessionPresetMedium
. De offisielle Apple-dokumentasjonene viser følgende tilgjengelige valg for denne innstillingen:
- AVCaptureSessionPresetPhoto
- Angir opptaksinnstillinger som passer for utskrift med høy oppløsning.
- AVCaptureSessionPresetHigh
- Angir opptaksinnstillinger som passer for høy kvalitet video og lydutgang.
- AVCaptureSessionPresetMedium
- Angir opptaksinnstillinger som passer for utgangs- og lydbitrater som er egnet for deling over WiFi.
- AVCaptureSessionPresetLow
- Angir opptaksinnstillinger som passer for utgangs- og lydbitrater som er egnet for deling over 3G.
- AVCaptureSessionPreset640x480
- Angir opptaksinnstillinger som er egnet for VGA-kvalitet (640x480 piksler) videoutgang.
- AVCaptureSessionPreset1280x720
- Angir opptaksinnstillinger som passer for 720p-kvalitet (1280x720pixel) videoutgang.
Ved å angi en høyere utdataverdi betyr det at du har mer data tilgjengelig for behandling og analyse i tillegg til et sluttutgangsbilde av høyere visuell kvalitet. Men fordelene kommer med en pris: tregere prosesshastigheter. Når du arbeider med video eller forsøker dynamisk objektgjenkjenning, vil du oppdage at tweaking denne innstillingen kan bidra dramatisk.
Vær også oppmerksom på at mens bestemte forhåndsinnstillinger er tilgjengelige (for eksempel 1280x720, 640x480), anbefales det vanligvis å bruke en av de mer generiske "høye", "middels" eller "lave" verdiene. Dette gjør søknaden mer bærbar og robust som den kan kjøre på enheter (nåværende eller fremtidige!) Som kanskje ikke støtter en gitt hardkodet verdi.
Linjer 8 - 10 opprette en AVCaptureDeviceInput
objekt, bruk opptaksenheten vi opprettet tidligere, og legg deretter objektet til vår opptakssesjon.
Linjer 14 - 17 oppsett an AVCaptureDeviceOutput
objekt og legg det til vår fange økt. På linje 15 konfigurerer vi video ut
å alltid kaste bort rammer som mottas sent. Du må huske på at opptakssesjonen skal administrere mange rammer hver eneste sekund, og på grunn av avvik i prosessorbelastning er det mulig at noen av rammene kan komme senere enn andre. Fordi vi bygger et program som forsøker å generere et levende vindu inn i verden bak iPhone, bryr vi oss ikke om sena rammer, så vi kaster bort dem. Vi ønsker bare å behandle og vise bilder som er like nær gjeldende millisekund som mulig.
Etter å ha konfigurert inngang og utdata fra opptakssesjonen, er det på tide å binde forhåndsvisningslaget deklarert i grensesnittet til videoopptaket for opptakssesjon. Dette vil gi brukerne et digitalt vindu av virkeligheten rundt dem.
// Bind forhåndsvisning lag for å fange økt datakameraPreviewLayer = [[AVCaptureVideoPreviewLayer tildeling] initWithSession: cameraCaptureSession]; CGRect layerRect = self.view.bounds; kameraPreviewLayer.bounds = self.view.bounds; cameraPreviewLayer.position = CGPointMake (CGRectGetMidX (layerRect), CGRectGetMidY (layerRect)); kameraPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; // Legg til forhåndsvisningslag til UIView-lag [self.view.layer addSublayer: cameraPreviewLayer];
De fem første linjene i kodenavnet ovenfor tilordner forhåndsvisningslaget og endrer størrelsen på lagene for å fylle skjermbildet.
Neste linje angir videGravity
eiendom. Denne innstillingen styrer hvordan videobilder skal gjengis i forhåndsvisningslaget. Den offisielle Apple-dokumentasjonen beskriver følgende muligheter:
- AVLayerVideoGravityResize
- Angir at videoen skal strekkes for å fylle lagets grenser.
- AVLayerVideoGravityResizeAspect
- Angir at spilleren skal bevare videoens aspektforhold og tilpasse videoen innenfor lagets grenser.
- AVLayerVideoGravityResizeAspectFill
- Angir at spilleren skal bevare videoens aspektforhold og fylle lagets grenser.
Som du kan fortelle fra koden ovenfor, tror jeg det AVLayerVideoGravityResizeAspectFill
passer best til brukssaken vår.
Den siste linjen over er ansvarlig for å legge til forhåndsvisningen CALayer
til visningsstyringslaget, som gjør det synlig for brukeren.
I de seks trinnene ovenfor har vi opprettet vårt prosjekt og opprettet en AVCaptureSession
bundet til det bakre kameraet for inngang og et tilpasset forhåndsvisningslag for utdata. Alt som gjenstår på dette stadiet, er faktisk å begynne å streame video ved å starte opptakssesjonen:
// Start kameraopptak [cameraCaptureSession startRunning];
Med oppstartsprosessinitialiseringen fullført, virker det nå som en god tid å frigjøre minnet vi tildelte. Gjør det med følgende kode:
- (void) viewDidUnload [super viewDidUnload]; [CameraCaptureSession stopRunning]; [CameraCaptureSession release], kameraCaptureSession = nil; [kameraPreviewLayer release], kameraPreviewLayer = null; - (void) dealloc [cameraCaptureSession stopRunning]; [cameraCaptureSession release]; [kameraPreviewLayer release]; [super dealloc];
Hvis du lagrer, bygger og driver prosjektet etter å ha lagt til de ovennevnte kodelinjene, bør du kunne få et glimt på verden rundt deg rett gjennom iPhone-skjermen.
Denne opplæringen har gått deg gjennom prosessen med å bruke AVFoundation-rammen for å starte videoopptak og vise hver ramme i nærheten av sanntid på en iPhone-skjerm. På grunn av ubiquity av videokameraer rundt oss (samt iPhone Camera app), kan dette ikke virke som mye av en prestasjon, men det er virkelig! Dette er det første trinnet i mange utvidede virkelighetsapplikasjoner: digitalisering av brukerens syn på den oppfattede verden. Herfra kan vi fortsette i alle retninger fra å overføre tilpassede visninger til den virkelige rammen for å faktisk manipulere pixeldataene i verden for å forbedre eller endre visjonen om virkeligheten.
Den neste Mobiletuts + Premium-opplæringen i denne serien vil fortsette med å ta vårt digitale vindu av verden og gjøre det litt mer interessant. Hold deg oppdatert, og takk for å lese!