Applica filtri fotografici con Core Image in Swift

Cosa starai creando

La potenza del Core Image Framework

Core Image è una tecnologia di elaborazione e analisi delle immagini progettata per fornire un'elaborazione quasi in tempo reale per immagini fisse e video in iOS e OS X. Apple ha realizzato alcuni fantastici effetti fotografici preimpostati che puoi facilmente utilizzare per le tue app di fotografia, con nomi come Instant, Process, Seppia, Tonale, ecc.

Core Image Reference

La libreria di sviluppatori iOS fornisce una buona spiegazione dell'elaborazione dell'immagine Core Image nella Core Reference Reference Collection.

Ti suggerisco di consultare anche la pagina di riferimento del filtro immagine di base per ottenere un elenco completo di disponibili CIFilterS. Si prega di notare che non tutti questi sono compatibili con iOS; alcuni di loro funzionano solo su OS X. 

Useremo i seguenti filtri di Core Image:

  • CIPhotoEffectChrome
  • CISepiaTone
  • CIPhotoEffectTransfer
  • CIPhotoEffectTonal
  • CIPhotoEffectProcess
  • CIPhotoEffectNoir
  • CIPhotoEffectInstant
  • CIPhotoEffectFade

Nota:Questo tutorial è stato scritto utilizzando Xcode 7.3 e Swift 2.2, con un obiettivo di distribuzione impostato su 8.0, quindi la tua app funzionerà anche su dispositivi meno recenti.

Iniziamo!

Crea un progetto e aggiungi viste

Apri Xcode e crea un nuovo progetto, Applicazione iOS Single View. Scegliere veloce come la lingua e universale per dispositivi. Otterrai uno spazio vuoto UIViewController nello Storyboard e un paio di .veloce File: ViewController.swift e AppDelegate.swift.

Seleziona il controller nello Storyboard e imposta le sue dimensioni come iPhone da 3,5 pollici nel pannello di destra, sotto Metriche simulate. Questo ti aiuterà ad adattare le visualizzazioni per l'iPhone 4S, il dispositivo Apple con la dimensione dello schermo più piccola disponibile.

Non useremo il layout automatico in questo tutorial, perché incasina i layout su dispositivi più grandi come iPad e iPad Pro. Disabilitalo selezionando File Inspector e deselezionare Usa layout automatico. Quindi fare clic su Disabilita classi di dimensioni pulsante dal popup.

Ora trova un'immagine JPEG, dal web o dal tuo Mac, e trascinala sotto Assets.xcassets cartella nel pannello di navigazione Progetto. Lo useremo come immagine di esempio a cui possiamo applicare i nostri filtri. Dai un nome a questo file picture.jpg; lo chiameremo più avanti nel codice.

Dovrai trascinare alcune visualizzazioni aggiuntive nel controller. Seleziona la libreria degli oggetti nell'angolo in basso a destra di Xcode e trascina a UIView al centro dello schermo. Ridimensiona la vista a 320 x 320 px e centra orizzontalmente. 

Ora aggiungi due UIImageViews alla tua Storyboard, trovandoli nella libreria Object e trascinandoli nella main UIView. Ridimensiona queste visualizzazioni immagine per riempire quella vista principale (vedremo come impostare le loro proprietà di autorizzazione in seguito). Assegnare picture.jpg alla prima vista immagine con il pannello di controllo Attributi.

Quindi, trascina un UIScrollView nella parte inferiore dello schermo e impostare la larghezza per adattarla alla larghezza del controller. Puoi anche aggiungere un UILabel all'inizio del controller e impostare il suo testo su filtri. Questo sarà il titolo della tua app. 

Infine, aggiungi un UIButton nell'angolo in alto a sinistra dello schermo e fare il suo titolo Salvare.

Imposta la personalizzazione e le viste di layout

L'ispettore tagliail pannello può essere mostrato facendo clic sulla piccola icona del righello nell'angolo in alto a destra dello schermo. Fallo ora e inizia a modificare le dimensioni della vista selezionando UIButton. L'ispettore Dimensione mostrerà le sue coordinate x e y sullo schermo (tieni presente che x è 0 sul lato sinistro dello schermo e y è 0 in alto). Imposta la larghezza e l'altezza su 44 px.

Imposta la maschera di autoresizzazione del pulsante per attaccarla ai lati superiore e sinistro dello schermo.

Ora seleziona tutte le altre viste, una ad una e aggiusta le loro dimensioni e posizioni come segue:

Il titolo dell'app ha una larghezza di 320 px e un'altezza di 44 px e si attacca nella parte superiore dello schermo.

Le viste delle immagini hanno ciascuna una larghezza e un'altezza di 320 px.

Infine, la vista di scorrimento (per le opzioni di filtro) ha una larghezza di 320 px e un'altezza di 80 px.

Dichiarare le viste nel file .swift

Una delle più belle funzionalità di Xcode è la possibilità di dividere lo spazio di lavoro in due parti e avere lo Storyboard su un lato e un file Swift sull'altro lato. Per poterlo fare, è necessario fare clic su Assistente editore icona nell'angolo in alto a destra della finestra Xcode:

Se tuo ViewController è selezionato in Storyboard, la sezione destra mostrerà automaticamente il suo relativo .veloce file. Se ciò non accade, puoi provare a fare clic sul menu orizzontale nella parte superiore del file swift e passare Manuale a Automatico:

Ora aggiungiamo alcune delle nostre opinioni al ViewController.swift file. Dal Struttura del documento pannello, selezionare il UIView quello contiene i due UIImageViews, tieni premuto Controllo (o il tasto destro del mouse) e trascina il puntatore del mouse sotto per ottenere la dichiarazione della classe del tuo controller di visualizzazione.

Rilascia il pulsante del mouse e apparirà un popup. Digitare il nome del UIView-containerView-e fare clic su Collegare pulsante.

Hai appena aggiunto una dichiarazione per un IBOutlet di tipo UIView alla tua .veloce file. Fai la stessa cosa per le altre visualizzazioni di immagine: trascina la linea blu sotto ogni istanza che dichiarerai e dai il nome al primo immagine originale e il secondo imageToFilter. Assicurati che immagine originale è quello con picture.jpg come immagine. 

Quindi collegare il UIScrollView e nominalo filtersScrollView. Questo memorizzerà tutti i pulsanti per applicare i filtri alla tua immagine.  

Dichiareremo il nostro UIButton più tardi come un IBAction. Questo pulsante ci permetterà di salvare la nostra immagine filtrata nella libreria fotografica del nostro dispositivo.

Facciamo codice!

Creazione di una matrice di filtri di immagine di base

In Swift, puoi dichiarare le variabili globali semplicemente posizionandole all'esterno di a classe dichiarazione, nel nostro caso questo:

class ViewController: UIViewController  

Dobbiamo creare una serie di CIFilter nomi:

var CIFilterNames = ["CIPhotoEffectChrome", "CIPhotoEffectFade", "CIPhotoEffectInstant", "CIPhotoEffectNoir", "CIPhotoEffectProcess", "CIPhotoEffectTonal", "CIPhotoEffectTransfer", "CISepiaTone"]

Come accennato all'inizio di questo tutorial, dobbiamo utilizzare i nomi dei filtri originali Core Image affinché la nostra app li riconosca. Assegneremo questi filtri ai pulsanti che creeremo in seguito, applicando il filtro alla nostra immagine.

Nascondere la barra di stato

La maggior parte delle volte, potresti voler nascondere la barra di stato dallo schermo. Poiché Xcode 7.0, non è più possibile impostare la proprietà nascosta della barra di stato in Info.plist, quindi devi aggiungere questo metodo proprio sopra viewDidLoad ()

override func prefersStatusBarHidden () -> Bool return true 

Creazione dei pulsanti filtro

Il viewDidLoad () metodo è un'istanza predefinita che Xcode crea ogni volta che aggiungi un .veloce file al tuo progetto; viene chiamato quando viene caricato lo schermo e tutte le sue viste. Se volevi eseguire un'azione anche prima che ciò accada, potresti usare il viewDidAppear () o viewWillAppear () metodi, ma non è necessario. Quindi aggiungiamo alcune variabili di tipo CGFloat proprio sotto super.viewDidLoad ():

override func viewDidLoad () super.viewDidLoad () var xCoord: CGFloat = 5 let yCoord: CGFloat = 5 let buttonWidth: CGFloat = 70 let buttonHeight: CGFloat = 70 lascia gapBetweenButtons: CGFloat = 5

Questi valori sono necessari per posizionare una fila di pulsanti all'interno del nostro filtersScrollView. Come puoi vedere nel codice sopra, il xcoord è la posizione X in cui verrà posizionato un pulsante, yCoord è la posizione Y., buttonWidth e buttonHeight sono le sue dimensioni, e gapBetweenButtons è lo spazio tra ogni pulsante. 

Ora dobbiamo effettivamente creare i pulsanti usando a per loop che duplicherà una custom UIButton e inseriscilo nel filtersScrollView in base ai valori di cui sopra. 

Inserisci questo codice proprio sotto quelli CGFloat casi:

 var itemCount = 0 per i in 0 ...  

Vediamo cosa succede in questo codice. ItemCount è una variabile che useremo in seguito per aggiungere i nostri pulsanti di filtro come subviews di filtersScrollView. Si può notare che abbiamo dichiarato questa variabile con il var prefisso. Questo perché sarà modificato dal per ciclo continuo. Se vuoi dichiarare le costanti in Swift, usi il permettere prefisso, come abbiamo fatto per il filterButton.

Usando il nuovo per sintassi del loop di Swift 2.2, non è necessario scrivere io++ più. Il ciclo aumenterà io automaticamente contando da 0 al numero di elementi del CIFilterNames schieramento.

Dentro quello per loop, creiamo un pulsante personalizzato, impostiamo il suo CGRect valori, assegnagli un tag e aggiungi un'azione di destinazione ad esso che chiama una funzione che vedremo in seguito: filterButtonTapped ().

Per rendere il nostro pulsante un aspetto gradevole, con angoli arrotondati, utilizziamo il strato proprietà e impostare il suo raggio d'angolo su 6. Quindi si taglia l'immagine per essere contenuta nei suoi limiti, altrimenti coprirà gli angoli arrotondati.

Aggiungi l'immagine ai pulsanti e applica i filtri

Il prossimo pezzo di codice deve essere aggiunto sotto il commento del precedente:

 // Crea filtri per ogni pulsante lascia ciContext = CIContext (opzioni: nil) lascia coreImage = CIImage (image: originalImage.image!) Let filter = CIFilter (nome: "\ (CIFilterNames [i])") filter! .SetDefaults ( ) filter! .setValue (coreImage, forKey: kCIInputImageKey) lascia filteredImageData = filter! .valueForKey (kCIOutputImageKey) as! CIImage let filteredImageRef = ciContext.createCGImage (filteredImageData, fromRect: filteredImageData.extent) let imageForButton = UIImage (CGImage: filteredImageRef);

Qui inizializziamo a CIContext e CIImage per far funzionare Core Image immagine originale (picture.jpg) che ogni pulsante mostrerà. Quindi iniziamo una variabile di filtro di tipo CIFilter che verrà chiamato da ciascun pulsante attraverso il per loop basato sul CIFilterNames schieramento.

Nostro filtro l'istanza deve impostare lo stato predefinito e quindi diventa la chiave di input per le immagini. Quindi creiamo l'oggetto dati da esso e il suo riferimento dell'immagine, che useremo per creare un UIImage subito che sarà collegato al pulsante. 

Poiché i filtri che abbiamo selezionato per questo tutorial sono preconfigurati da Apple, non è necessario applicare alcun valore aggiuntivo (come intensità, colore, ecc.). Se vuoi ottenere informazioni su altri CIFilters, è possibile controllare la pagina di riferimento del filtro immagine di base.

Nell'ultima riga di questa sezione, abbiamo finalmente impostato l'immagine di sfondo del pulsante che abbiamo precedentemente creato.

 // Assegna l'immagine filtrata al pulsante filterButton.setBackgroundImage (imageForButton, forState: .Normal) 

Aggiunta di pulsanti al ScrollView

Solo qualche riga in più per completare la nostra viewDidLoad () metodo:

 // Aggiungi pulsanti nella vista di scorrimento xCoord + = buttonWidth + gapBetweenButton filtriScrollView.addSubview (filterButton) // END FOR LOOP // Ridimensiona Scroll Visualizza filtriScrollView.contentSize = CGSizeMake (buttonWidth * CGFloat (itemCount + 2), yCoord) / / END viewDidload ()

Stiamo aggiungendo i pulsanti come viste secondarie al filtersScrollView in base alla loro posizione e alla larghezza e allo spazio che devono mantenere tra di loro. Quindi finalmente chiudiamo il per ciclo continuo.

Infine, dobbiamo impostare il contentSize della nostra ScrollView per adattarsi a tutti i pulsanti. Ecco dove finalmente usiamo il ItemCount variabile precedentemente dichiarata, convertita in CGFloat (perché CGSizeMake non accetta Int valori).

L'azione del pulsante Filtro

Abbiamo quasi finito, con solo poche righe di codice!

Nel ViewController classe, fuori viewDidLoad (), creare il filterButtonTapper () funzione. Questo verrà chiamato ogni volta che tocchi uno dei pulsanti che abbiamo generato in precedenza.

func filterButtonTapped (sender: UIButton) let button = sender come UIButton imageToFilter.image = button.backgroundImageForState (UIControlState.Normal)

Dobbiamo creare un'istanza di UIButton prima, quindi impostare il imageToFilterL'immagine è basata sull'immagine di sfondo del pulsante, che è già stata filtrata dal codice inserito viewDidLoad ()

Assicurarsi che il UIImageView chiamato imageToFilter sovrappone il immagine originale, come mostrato di seguito, altrimenti l'app non mostrerà l'immagine elaborata perché l'immagine originale la nasconderà.

Salvataggio dell'immagine elaborata

Siamo alla fine di questo tutorial e c'è solo un'altra funzione da aggiungere al tuo .veloce file. Questo è il pulsante Salva che abbiamo precedentemente inserito nello Storyboard. tenere Controllo e il pulsante del mouse, trascinare una linea blu dal UIButton in uno spazio vuoto all'interno della classe, rilascia il pulsante del mouse e verrà visualizzato un nuovo popup. Qui devi cambiare il Connessione digitare a Azione e inserisci il nome del tuo metodo, in questo caso savePicButton-e fare clic su Collegare pulsante.

Hai creato un IBAction questa volta, ed ecco il codice che deve essere inserito in esso:

 // Salva l'immagine nel rullino fotografico UIImageWriteToSavedPhotosAlbum (imageToFilter.image !, nil, nil, nil) lascia alert = UIAlertView (titolo: "Filters", messaggio: "L'immagine è stata salvata nella Photo Library", delegato: nil, cancelButtonTitle : "OK") alert.show () 

La prima riga salva semplicemente l'immagine contenuta in imageToFilter direttamente nella Photo Library del tuo dispositivo o iOS Simulator. Quindi spariamo un semplice UIAlertView ciò conferma che l'operazione è stata effettuata.

OK, eseguiamo la nostra app e vediamo cosa succede se tocchiamo i pulsanti in basso. Se hai fatto tutto correttamente, la tua app dovrebbe apparire così:



Grazie per la lettura, e ci vediamo la prossima volta! Consulta alcuni dei nostri altri tutorial sullo sviluppo di app Swift e iOS.