Legge Blur Effekter på iOS

Adding Blur Effekter på iOS
53
Del
31
Del
Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

Innledning

Med iOS 7, vi så et skifte i Apples design paradigme for mobile enheter. Ikke bare gjorde de vedta den såkalte flat design, Apple også lagt noen elementer til dette mønsteret selv. En av disse tilsetninger er bruken av uskarpe-gjennomskinnelig bakgrunn for å formidle begrepet dybde og sammenheng. Ta Control Center
for eksempel, tåkelegger det innholdet i visningen bak det som det blir trukket opp. Dette gir brukeren en følelse av at det er plassert ovenfor
annet innhold på skjermen, og fortjener fokus. Det gjør det uten å gjøre brukeren mister oversikten over hvor hun er i appen.

Selv om uskarphet og gjennomskinnelighet er brukt over hele operativsystemet på iOS 7, ikke iOS SDK ikke gi oss noen APIer til oppnå en lignende effekt. I denne opplæringen, vil jeg gå gjennom noen metoder for å skape uklare synspunkter ved å lage prøven app vist nedenfor.

Vår sample app vil ha en visning på bunnen, som kan bli avslørt ved å trekke den opp . Utsikten er gjennomsiktig og visker ut innhold som er under den i hierarkiet visning, ligner Control Center på iOS 7.

1. Prosjektet Setup

Oversikt

Den app som vi skal bygge vil vise et bilde sammen med bildets navn og forfatter, vises i en hvit sirkel. Det vil også være en liten rektangulær visning nederst på skjermen som visker ut bilder og som kan trekkes opp for å vise mer informasjon om bildet.

Jeg kommer til å anta at du allerede vet hvordan du jobbe med grunnleggende elementer i brukergrensesnittet, for eksempel utsikt, utsikt image, og bla utsikt. I denne opplæringen, vil vi fokusere på hierarkiet utsikt og utsikten som vi trenger for å skape den blur effekt.

Ta en titt på bildet over. Det trekker fra hverandre hierarkiet visningen for å skape blur effekten vi er ute etter. De viktigste komponentene er:

Bakgrunn View:
Denne visningen viser bilder og kreditter. Dette er av den oppfatning at vi kommer til å dimme

Uklart Bilde:..
Denne visningen inneholder en uskarp versjon av innholdet i bakgrunnen visningen

Vis Mask:.
Utsikten masken er en ugjennomsiktig oppfatning at vi skal bruke til å maskere uskarpt bilde

Bla View:
bla visning er utsikten som inneholder ytterligere informasjon om bildet. Rulle syn er offset brukes til å øke eller redusere masken visning høyde. Dette vil resultere i uskarpe bildet for å avsløre seg selv som svar på rulling av bla syn.

Resources

Alle bildene, rammer og andre filer som er nødvendige for denne opplæringen er inkludert i kildefilene for denne opplæringen. Klone depotet fra GitHub eller laste ned kildefilene å følge med.

2. Opprette brukergrensesnittet

1. Oversikt

Åpne RootViewController.m i Xcode og ta en titt på sin loadView metoden. Du kan få en fugleperspektiv på hvordan brukergrensesnittet er lagt ut ved å se på gjennomføringen av denne metoden. Det er tre hoved subviews i vår søknad:

Header View:
Viser programmets navn

Content View:
Viser bilde og studiepoeng

Bla Vis
:
Inkluderer tilleggsinformasjon om en rulle uskarpt syn

I stedet for å samles på loadView metoden med initialisering og konfigurere subviews, er hjelpemetoder som brukes til å gjøre de tunge løftene:
//innhold utsikt [self.view addSubview: [selvtillit createContentView]]; //Header view [self.view addSubview: [selvtillit createHeaderView]]; //Bla view [self.view addSubview: [selvtillit createScrollView]];
2. Opprette Header Vis

Den header visning inneholder en gjennomsiktig rektangel og en tekstetikett med programmets navn Anmeldelser - (UIView *) createHeaderView {UIView * headerView = [[UIView alloc] initWithFrame. CGRectMake (0 , 0, self.view.frame.size.width, 60)]; headerView.backgroundColor = [UIColor colorWithRed: 229 /255,0 grønn: 39 /255,0 blå: 34 /255,0 alfa: 0,6]; UILabel * title = [[UILabel alloc] initWithFrame: CGRectMake (0, 20, self.view.frame.size.width, 40)]; title.text = @ "Dynamic Blur Demo"; ... [HeaderView addSubview: title]; returnere headerView;}
3. Opprette innhold Vis

Innholdet visningen viser bildet og det inkluderer også foto studiepoeng i en hvit sirkel Anmeldelser - (UIView *) createContentView {UIView * contentView = [[UIView alloc] initWithFrame. Selv .view.frame]; //Bakgrunnsbilde UIImageView * contentImage = [[UIImageView alloc] initWithFrame: contentView.frame]; contentImage.image = [UIImage imageNamed: @ "demo-bg"]; [contentView addSubview: contentImage]; //Photo credits UIView * creditsViewContainer = [[UIView alloc] initWithFrame: CGRectMake (self.view.frame.size.width /2 - 65, 335, 130, 130)]; metaViewContainer.backgroundColor = [UIColor whiteColor]; metaViewContainer.layer.cornerRadius = 65; [contentView addSubview: creditsViewContainer]; UILabel * photoTitle = [[UILabel alloc] initWithFrame: CGRectMake (0, 54, 130, 18)]; photoTitle.text = @ "Peach Garden"; ... [MetaViewContainer addSubview: photoTitle]; UILabel * fotograf = [[UILabel alloc] initWithFrame: CGRectMake (0, 72, 130, 9)]; photographer.text = @ "av Cas Cornelissen"; ... [MetaViewContainer addSubview: fotograf]; returnere contentView;}
4. Opprette rulle Vis

Rulle visning inneholder mer informasjon om bildet og en uskarp versjon av bildet. Rulle Utsikten er omtrent dobbelt lengden av skjermen, med den nederste halvdelen inneholder teksten visning og bildevisningen. Ved å aktivere paging på rulle syn, vil rulle vise innholdet smekk til toppen eller bunnen av visningen, avhengig av rulle visningens offset Anmeldelser -. (UIView *) createScrollView {UIView * containerView = [[UIView alloc] initWithFrame: self.view.frame]; blurredBgImage = [[UIImageView alloc] initWithFrame: CGRectMake (0, 0, self.view.frame.size.width, 568)]; [blurredBgImage setContentMode: UIViewContentModeScaleToFill]; [containerView addSubview: blurredBgImage]; UIScrollView * scrollView = [[UIScrollView alloc] initWithFrame: self.view.frame]; scrollView.contentSize = CGSizeMake (self.view.frame.size.width, self.view.frame.size.height * 2 - 110); scrollView.pagingEnabled = JA; ... [ContainerView addSubview: scrollView]; UIView * slideContentView = [[UIView alloc] initWithFrame: CGRectMake (0, 518, self.view.frame.size.width, 508)]; slideContentView.backgroundColor = [UIColor clearColor]; [scrollView addSubview: slideContentView]; UILabel * slideUpLabel = [[UILabel alloc] initWithFrame: CGRectMake (0, 6, self.view.frame.size.width, 50)]; slideUpLabel.text = @ "Photo informasjon"; ... [SlideContentView addSubview: slideUpLabel]; UIImageView * slideUpImage = [[UIImageView alloc] initWithFrame: CGRectMake (self.view.frame.size.width /2 - 12, 4, 24, 22,5)]; slideUpImage.image = [UIImage imageNamed: @ "up-arrow.png"]; [slideContentView addSubview: slideUpImage]; UITextView * detailsText = [[UITextView Alloc] initWithFrame: CGRectMake (25, 100, 270, 350)]; detailsText.text = @ "Lorem ipsum ... laborum"; ... [SlideContentView addSubview: detailsText]; returnere containerView;}
3. Tar et fotografi

For å dimme en visning, må vi først ta et øyeblikksbilde av innholdet og ha den klar i form av et bilde. vi kan da uklart bildet og bruke det som bakgrunn på en annen visning. La oss først se hvordan vi kan ta et øyeblikksbilde av innholdet i en UIView objekt

I iOS 7, lagt Apple en ny metode for å UIView for å ta bilder av en visning innhold, drawViewHierarchyInRect:. AfterScreenUpdates :. Denne metoden tar et øyeblikksbilde av utsikten innhold, herunder eventuelle subviews den inneholder.

La oss definere en metode i ViewController klassen som godtar en UIView objekt og returnerer en UIImage, et øyeblikksbilde av utsikten innhold. Anmeldelser - (UIImage *) takeSnapshotOfView: (UIView *) visning {UIGraphicsBeginImageContext (CGSizeMake (view.frame.size.width, view.frame.size.height)); [view drawViewHierarchyInRect: CGRectMake (0, 0, view.frame.size.width, view.frame.size.height) afterScreenUpdates: YES]; UIImage * image = UIGraphicsGetImageFromCurrentImageContext (); UIGraphicsEndImageContext (); returnere image;}
Trinn 1: Begynn et nytt bilde Context

Et bilde sammenheng er et bitmap-basert grafikk kontekst som du kan bruke til å tegne og manipulere bilder. UIView nye metode drawViewHierarchyInRect: afterScreenUpdates: rastrerer den UIView og trekker innholdet i det aktuelle bildet sammenheng

Dette betyr at før vi kaller denne metoden, må vi først opprette et nytt bilde kontekst ved å påberope UIGraphicsBeginImageContext, passerer i. den nødvendige størrelsen for bildet sammenheng

Trinn 2:. Ta Snapshot

Med bilde sammenheng satt opp, kan vi kalle visningens drawViewHierarchyInRect: afterScreenUpdates: metode. Det andre argumentet angir om øyeblikksbildet skal inneholde vise eksisterende innhold eller må inkludere eventuelle nye endringer før du tar snapshot

Trinn 3:. Lag Bilde fra bilde Context

Vi kan få innholdet i bildesammenheng, snapshot av visningen, ved å kalle UIGraphicsGetImageFromCurrentImageContext. Denne funksjonen returnerer en UIImage objekt

Trinn 4:.. End Bilde Context

Når du har opprettet snapshot, fjerner vi grafikk sammenheng fra bunken ved å påberope UIGraphicsEndImageContext


4. Tåkelegge Snapshot

Når du har snapshot, vi kan dimme det ved hjelp av en rekke teknikker. I denne opplæringen, vil jeg dekke tre teknikker:

uskarphet med Core Image rammeverket

uskarphet ved bruk av Brad Larson GPUImage rammeverk

uskarphet ved hjelp av Apples UIImage + ImageEffects kategori

Alternativ 1: Core Image

Core Image er et bildebehandlings rammeverk utviklet og vedlikeholdt av Apple. Den bruker en GPU eller CPU gjengivelse vei til å behandle bilder i nær sanntid.

Core Image gir oss en rekke filtre som kan brukes til å utføre operasjoner som spenner fra å endre et bildes fargetone eller metning til ansiktsgjenkjenning .

CIGaussianBlur er ett av filtrene inkludert i Core Image rammeverket og kan brukes til å dimme bilder. Tåkelegge et bilde med Core Image er ganske enkelt som du kan se nedenfor Anmeldelser - (UIImage *) blurWithCoreImage: (UIImage *) sourceImage {CIImage * inputImage = [CIImage imageWithCGImage: sourceImage.CGImage].; //Påfør Affine-Clamp filter for å strekke bildet slik at det ikke skjer //ser krympet når Gaussian Blur påføres CGAffineTransform forvandle = CGAffineTransformIdentity; CIFilter * clampFilter = [CIFilter filterWithName: @ "CIAffineClamp"]; [clampFilter SetValue: inputImage Forkey: @ "inputImage"]; [clampFilter SetValue: [NSValue valueWithBytes: & forvandle objCType:encode (CGAffineTransform)] Forkey: @ "inputTransform"]; //Påfør Gaussian blur filter med radius på 30 CIFilter * gaussianBlurFilter = [CIFilter filterWithName: @ "CIGaussianBlur"]; [gaussianBlurFilter SetValue: clampFilter.outputImage Forkey: @ "inputImage"]; [gaussianBlurFilter SetValue: @ 30 Forkey: @ "inputRadius"]; CIContext * kontekst = [CIContext contextWithOptions: null]; CGImageRef CGImage = [sammenheng createCGImage: gaussianBlurFilter.outputImage fromRect: [inputImage grad]]; //Sett opp utgang sammenheng. UIGraphicsBeginImageContext (self.view.frame.size); CGContextRef outputContext = UIGraphicsGetCurrentContext (); //Inverter bilde koordinerer CGContextScaleCTM (outputContext, 1,0, -1,0); CGContextTranslateCTM (outputContext, 0, -self.view.frame.size.height); //Tegn basisbildet. CGContextDrawImage (outputContext, self.view.frame, CGImage); //Påfør hvit fargetone CGContextSaveGState (outputContext); CGContextSetFillColorWithColor (outputContext, [UIColor colorWithWhite: en alpha: 0,2] .CGColor); CGContextFillRect (outputContext, self.view.frame); CGContextRestoreGState (outputContext); //Output bildet er klar. UIImage * outputImage = UIGraphicsGetImageFromCurrentImageContext (); UIGraphicsEndImageContext (); returnere outputImage;}

La oss bryte koden ovenfor blokk ned:

Vi først opprette en CIImage objekt fra UIImage objekt. Når du arbeider med Core Image rammeverket, er bilder representert ved CIImage stedene.

  • Avhengig av blur radius, søker en Gaussian Blur til et bilde vil litt krympe bildet. For å omgå dette problemet, strekker vi bildet litt ved å påføre et annet filter, CIAffineClamp, før du påfører Gaussian blur filter.
  • Vi deretter ta produksjonen og gi det til CIGaussianBlur filter sammen med en blur radius 30.

    Vi kunne ta utgang, konvertere den til en CGImage, og bruke det i søknaden vår. Imidlertid vil vi legge til en hvit tone på bildet for å sikre at bildets beskrivelse er lett leselig. For å legge til en hvit fargetone, legger vi til en semi-transparent hvit fill over bildet. For å gjøre dette, skaper vi et nytt bilde kontekst og fyll den med en hvit farge med en alfa verdi på 0,2.
  • Som vi så tidligere, vi så får en UIImage objekt fra bildet sammenheng og kast av bildet sammenheng

    Alternativ 2:. GPUImage

    GPUImage er en åpen kildekode-iOS rammeverk for bilde- og videobehandling, skapt og vedlikeholdt av Brad Larson. Det inkluderer en samling av GPU-akselererte filtre som kan brukes på bilder, live kamera video, og filmer.

    GPUImage rammeverket er inkludert i kildefilene for denne opplæringen, men legger rammene til dine egne prosjekter er veldig enkelt:


      Start ved å laste ned rammeverket eller kloning depotet fra GitHub

      Åpne et terminalvindu, navigere til GPUImage mappe, og kjøre. bygge skriptet build.sh
      å kompilere rammeverket.

      Kopier GPUImage.framework
      fra bygge
      mappen til prosjektets mappen og deretter dra og slippe den inn i Prosjekt Navigator

      Du kan deretter bruke GPUImage rammeverket i prosjektet ved å importere de rammer overskrifter, #import. < GPUImage /GPUImage.h >.

      GPUImage rammeverket inneholder filtre som ligner på dem i Core Image rammeverket. For vår prøveprogrammet, er vi interessert i to filtre,, GPUImageGaussianBlurFilter og GPUImageiOSBlurFilter
      - (UIImage *) blurWithGPUImage:. (UIImage *) sourceImage {//Gaussian Blur GPUImageGaussianBlurFilter * blurFilter = [[GPUImageGaussianBlurFilter Alloc] init ]; blurFilter.blurRadiusInPixels = 30,0; tilbake [blurFilter imageByFilteringImage: sourceImage];}

      Som du kan se, GPUImage filtre er enklere å bruke enn de av Core Image rammeverket. Etter initialisering filteret objekt, er alt du trenger å gjøre konfigurere filteret og skal gi det et bilde som filteret må brukes. Den imageByFilteringImage: Metoden returnerer en UIImage objekt

      I stedet for GPUImageGaussianblur klasse, kan du også bruke GPUImageiOSblur klassen slik:.
      //IOS Blur GPUImageiOSBlurFilter * blurFilter = [[ ,,,0],GPUImageiOSBlurFilter Alloc] init]; blurFilter.blurRadiusInPixels = 30,0;

      GPUImageiOSblur klasse replikerer blur effekten du kan se i Control Center på iOS 7. Så, i motsetning til Core Image tilnærming, du trenger ikke å skrive ekstra kode til å farge den uskarpt bilde <. .no>
      Alternativ 3: UIImage + ImageEffects

      Under fjorårets WWDC, ga Apple en diskusjon om Core Image effekter og teknikker i som innførte de en kategori på UIImage kalt ImageEffects
      . ImageEffects
      kategorien bruker Apples høy ytelse vImage
      bildebehandling rammeverk, en del av Accelerate
      rammeverk, for å utføre de nødvendige beregninger. Dette gjør det en rask og enkel måte å utføre uskarphet på iOS.
      Kategorien legger til følgende metoder UIImage class:


      applyLightEffect

      applyExtraLightEffect

      applyDarkEffect

      applyTintEffectWithColor:

      applyBlurWithRadius:tintColor:saturationDeltaFactor:maskImage:

      These metoder kan kalles direkte på et bilde for å oppnå ønsket blur effekt. Den applyBlurWithRadius: tintColor: saturationDeltaFactor: maskImage: metoden kan brukes med en rekke argumenter som lar deg finjustere slør drift

      Du kan laste ned Apples ImageEffects
      prøve prosjekt fra Apples utvikler. nettside og bruke det i prosjektene
      #import "UIImage + ImageEffects.h" ...- (UIImage *) blurWithImageEffects:. (UIImage *) image {return [image applyBlurWithRadius: 30 tintColor: [UIColor colorWithWhite: en alpha : 0,2] saturationDeltaFactor: 1,5 maskImage: null];}
      5. Maskering uskarpt bilde

      I prøven app, ser det ut som om vi er dynamisk uskarphet fotografiet, men det er ikke tilfelle. Vi bruker et lite triks som kalles maskering. I stedet for å kontinuerlig ta bilder og uskarphet dem til å skape den ønskede effekt, tar vi bare ett bilde, dimme det, og bruke det i kombinasjon med en maske.

      Som vist i figuren i begynnelsen av denne opplæringen, vi justere uskarpt syn med bakgrunnen visningen under. Vi deretter opprette en visning med en høyde på 50 poeng og en ugjennomsiktig bakgrunn, og legg den i bunnen av skjermen. Vi bruker denne visningen til å maskere uskarpt bilde
      blurredBgImage.layer.mask = bgMask.layer;.

      Vi oppdaterer rammen av masken visning som bla visningen blir rullet. For å gjøre dette, vi gjennomføre en av de delegere metoder for UIScrollViewDelegate protokollen, scrollViewDidScroll :, og oppdatere maskens ramme med hensyn til rulle visning vertikale innhold offset Anmeldelser - (void) scrollViewDidScroll:. (UIScrollView *) scrollView {bgMask .frame = CGRectMake (bgMask.frame.origin.x, self.view.frame.size.height - 50 - scrollView.contentOffset.y, bgMask.frame.size.width, bgMask.frame.size.height + scrollView.contentOffset .Y);}

      Ved å oppdatere masken, ser det ut som om vi er dynamisk uskarphet fotografiet under rulle visning. Det er alt. Du har nå en vakker, blur effekt, lik den du ser i kontrollsenteret på iOS.

      6. Ytelse

      Med de ovennevnte teknikker i tankene, lurer du kanskje på hvilken som er best når det gjelder ytelse. For å hjelpe deg å avgjøre, jeg kjørte noen tester på en iPhone 5S og 5C. . Ta en titt på følgende grafer

      Disse grafene fortelle oss følgende:

      GPUImage rammeverket utfører den tregeste på iPhone 5C på grunn av sin tregere GPU. Dette er ikke overraskende siden rammen er veldig avhengig av GPU.

    1. ImageEffects kategorien gir best resultater på begge enhetene. Det er også interessant å se at den tiden som trengs for å tåkelegge et bilde øker med blur radius.

      Mens blurring bildene aldri tok lenger tid enn 220ms på iPhone 5S, iPhone 5C trengte opp til 1.3s å utføre den samme oppgaven. Dette viser tydelig at uskarphet effekter bør brukes med omhu og tynt.

      For å redusere tiden som kreves for å tåkelegge et bilde, kan vi redusere størrelsen på bildet som vi bruke blur filter på. Siden vi utfører en uklarhet og de finere detaljene i bildet vil ikke være synlig uansett, kan vi downsample bildet uten å kjøre inn i problemer. Å ta en mindre snapshot, oppdaterer vi gjennomføringen av takeSnapshotOfView: metode som følger:
      - (UIImage *) takeSnapshotOfView: (UIView *) visning {CGFloat reductionFactor = 1,25; UIGraphicsBeginImageContext (CGSizeMake (view.frame.size.width /reductionFactor, view.frame.size.height /reductionFactor)); [view drawViewHierarchyInRect: CGRectMake (0, 0, view.frame.size.width /reductionFactor, view.frame.size.height /reductionFactor) afterScreenUpdates: Ja]; ... Retur image;}

      For å redusere tiden det tar å dimme snapshot videre, kan vi bruke alternative blurring teknikker, for eksempel en boks uskarphet. Selv om resultatet vil være annerledes enn for en Gaussian Blur, det tar kortere tid å dimme et bilde med en boks uskarphet.

      Konklusjon

      Blur er definitivt et flott tillegg til brukergrensesnitt design på iOS. Men uansett hvor fantastisk din søknad brukergrensesnitt ser ut, hvis det ikke fungerer godt, blur effektene vil ikke forbedre din søknad.

      Basert på ovennevnte resultattall, ser vi at uskarphet er faktisk en kostbar effekt. Men ved å optimalisere parametrene, slik som blur radius og bildestørrelse, velge riktig tåkelegge teknikk, og ved hjelp av noen triks, kan vi oppnå svært interessante effekter uten at programmets ytelse.

      I iOS 8, har Apple innført UIVisualEffectView, som lar utviklere å veldig lett å bruke uklarhet og røre effekter til utsikt. Hvis du ikke kan vente til iOS 8 er offisielt lansert, kan du teste disse effektene ved å laste ned beta av Xcode 6.