Anwenden von Fotofiltern mit Core Image in Swift

Was Sie erstellen werden

Die Kraft des Core Image Framework

Core Image ist eine Bildverarbeitungs- und Analysetechnologie, die eine Echtzeitverarbeitung für Stand- und Videobilder in iOS und OS X ermöglicht. Apple hat einige großartige vorgefertigte Fotoeffekte entwickelt, die Sie problemlos für Ihre Foto-Apps verwenden können Namen wie Instant, Process, Sepia, Tonal usw.

Kernbildreferenz

Die iOS-Entwicklerbibliothek bietet eine gute Erläuterung der Verarbeitung von Core Image-Bildern in der Core Image Reference Collection.

Ich schlage vor, dass Sie auch die Core Image Filter Reference-Seite auschecken, um eine vollständige Liste der verfügbaren Informationen zu erhalten CIFilters. Bitte beachten Sie, dass nicht alle davon mit iOS kompatibel sind. Einige von ihnen funktionieren nur unter OS X. 

Wir werden die folgenden Core Image-Filter verwenden:

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

Hinweis:Dieses Tutorial wurde unter Verwendung von Xcode 7.3 und Swift 2.2 geschrieben, wobei das Implementierungsziel auf 8.0 gesetzt ist. Ihre App funktioniert daher auch auf älteren Geräten.

Lass uns anfangen!

Erstellen Sie ein Projekt und fügen Sie Ansichten hinzu

Öffnen Sie Xcode und erstellen Sie ein neues Projekt, iOS Single View-Anwendung. Wählen Schnell als die Sprache und Universal für Geräte. Du bekommst ein Leerzeichen UIViewController im Storyboard und ein paar .schnell Dateien: ViewController.swift und AppDelegate.swift.

Wählen Sie den Controller im Storyboard aus und legen Sie seine Größe als fest iPhone 3,5 Zoll im rechten Feld unter Simulierte Metriken. Dies hilft Ihnen, Ansichten für das iPhone 4S anzupassen, das Apple-Gerät mit der kleinsten verfügbaren Bildschirmgröße.

In diesem Lernprogramm wird kein automatisches Layout verwendet, da Layouts auf größeren Geräten wie dem iPad und dem iPad Pro durcheinander gebracht werden. Deaktivieren Sie es, indem Sie auswählen Dateiinspektor und deaktivieren Verwenden Sie Auto Layout. Klicken Sie dann auf Größenklassen deaktivieren Schaltfläche aus dem Popup.

Suchen Sie nun ein JPEG-Bild - entweder aus dem Internet oder von Ihrem Mac - und ziehen Sie es unter das Symbol Assets.xcassets Ordner im Projektnavigatorfenster. Wir werden dies als Beispielbild verwenden, auf das wir unsere Filter anwenden können. Benennen Sie diese Datei picture.jpg; Wir werden es später im Code aufrufen.

Sie müssen einige zusätzliche Ansichten in den Controller ziehen. Wählen Sie die Objektbibliothek in der rechten unteren Ecke von Xcode aus und ziehen Sie eine UIView zur Mitte des Bildschirms. Ändern Sie die Größe der Ansicht auf 320 x 320 px und zentrieren Sie sie horizontal. 

Fügen Sie jetzt zwei hinzu UIImageViews zu Ihrem Storyboard, indem Sie sie in der Objektbibliothek finden und in den Hauptbereich ziehen UIView. Ändern Sie die Größe dieser Bildansichten, um diese Hauptansicht zu füllen (wir werden später sehen, wie Sie ihre automatischen Größeneinstellungen festlegen). Zuordnen picture.jpg zur ersten Bildansicht mit dem Attribut-Inspektorfenster.

Ziehen Sie als nächstes eine UIScrollView am unteren Rand des Bildschirms und stellen Sie seine Breite auf die Breite des Controllers ein. Sie können auch eine hinzufügen UILabel an der Oberseite des Controllers und setzen Sie den Text auf Filter. Dies ist der Titel Ihrer App. 

Zum Schluss fügen Sie ein UIButton in der oberen linken Ecke des Bildschirms und machen Sie den Titel sparen.

Stellen Sie die Ansicht für automatisches Ändern und Layout ein

Der GrößeninspektorSie können das Panel anzeigen, indem Sie auf das kleine Lineal-Symbol in der rechten oberen Ecke des Bildschirms klicken. Tun Sie das jetzt und beginnen Sie mit der Bearbeitung der Ansichtsgrößen, indem Sie die Option auswählen UIButton. Der Größeninspektor zeigt Ihnen seine x- und y-Koordinaten auf dem Bildschirm an (beachten Sie, dass x auf der linken Seite des Bildschirms 0 und oben auf y 0 ist). Stellen Sie die Breite und Höhe auf 44 px ein.

Stellen Sie die automatische Größenänderungsmaske der Schaltfläche so ein, dass sie an der oberen und linken Seite des Bildschirms angebracht wird.

Wählen Sie nun nacheinander alle anderen Ansichten aus und passen Sie Größe und Position wie folgt an:

Der Titel der App hat eine Breite von 320 px und eine Höhe von 44 px und wird am oberen Rand des Bildschirms angehängt.

Die Bildansichten haben jeweils eine Breite und Höhe von 320 px.

Schließlich hat die Bildlaufansicht (für Filteroptionen) eine Breite von 320 px und eine Höhe von 80 px.

Ansichten in der .swift-Datei deklarieren

Eine der schönsten Funktionen von Xcode ist die Möglichkeit, den Arbeitsbereich in zwei Teile aufzuteilen und das Storyboard auf einer Seite und eine Swift-Datei auf der anderen Seite zu haben. Dazu müssen Sie auf das Symbol klicken Schnittassistenz Symbol in der oberen rechten Ecke Ihres Xcode-Fensters:

Wenn dein ViewController Wenn Sie im Storyboard die Option auswählen, wird im rechten Bereich automatisch die relative Position angezeigt .schnell Datei. Sollte dies nicht der Fall sein, können Sie versuchen, auf das horizontale Menü oben in der Swift-Datei zu klicken und zu wechseln Handbuch zu Automatik:

Lassen Sie uns nun einige unserer Ansichten mit dem verbinden ViewController.swift Datei. Von dem Dokument Gliederung Wählen Sie das Panel aus UIView das enthält die beiden UIImageViewHalten Sie gedrückt Steuerung (oder die rechte Maustaste), und ziehen Sie den Mauszeiger darunter, um die Klassendeklaration Ihres View-Controllers zu erhalten.

Lassen Sie die Maustaste los und es erscheint ein Popup. Geben Sie den Namen der ein UIView-containerView-und klicken Sie auf die Verbinden Taste.

Sie haben gerade eine Deklaration für ein hinzugefügt IBOutlet vom Typ UIView zu deinem .schnell Datei. Machen Sie dasselbe für die anderen Bildansichten: Ziehen Sie die blaue Linie unter jede Instanz, die Sie deklarieren, und nennen Sie die erste Original Bild und der zweite imageToFilter. Stelle sicher das Original Bild ist der mit picture.jpg als bild. 

Dann verbinden Sie die UIScrollView und nennen Sie es filtersScrollView. Dadurch werden alle Schaltflächen zum Anwenden von Filtern auf Ihr Bild gespeichert.  

Wir erklären unsere UIButton später als IBAction. Mit dieser Schaltfläche können wir unser gefiltertes Bild in der Fotobibliothek unseres Geräts speichern.

Lassen Sie uns Code schreiben!

Erstellen eines Arrays von Core Image-Filtern

In Swift können Sie globale Variablen deklarieren, indem Sie sie einfach außerhalb von platzieren Klasse Erklärung, in unserem Fall diese:

Klasse ViewController: UIViewController  

Wir müssen ein Array von erstellen CIFilter Namen:

var CIFilterNames = ["CIPhotoEffectChrome", "CIPhotoEffectFade", "CIPhotoEffectInstant", "CIPhotoEffectNoir", "CIPhotoEffectProcess", "CIPhotoEffectTonal", "CIPhotoEffectTransfer", "CISepiaTria".

Wie zu Beginn dieses Tutorials erwähnt, müssen wir die ursprünglichen Core Image-Filternamen verwenden, damit sie von unserer App erkannt werden können. Wir werden diese Filter den Schaltflächen zuweisen, die wir später erstellen werden, wodurch der Filter auf unser Bild angewendet wird.

Statusleiste ausblenden

In den meisten Fällen möchten Sie die Statusleiste auf Ihrem Bildschirm ausblenden. Seit Xcode 7.0 ist es nicht mehr möglich, die ausgeblendete Eigenschaft der Statusleiste in festzulegen Info.plist, Sie müssen diese Methode also oben hinzufügen viewDidLoad ()

überschreiben func bevorzugtStatusBarHidden () -> Bool return true 

Erstellen der Filterschaltflächen

Das viewDidLoad () method ist eine Standardinstanz, die Xcode jedes Mal erstellt, wenn Sie a hinzufügen .schnell Datei zu Ihrem Projekt; Es wird aufgerufen, wenn der Bildschirm und alle seine Ansichten geladen werden. Wenn Sie schon vorher eine Aktion ausführen möchten, können Sie die viewDidAppear () oder viewWillAppear () Methoden, aber wir müssen nicht. Fügen wir also einige Variablen vom Typ hinzu CGFloat gleich darunter super.viewDidLoad ():

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

Diese Werte werden benötigt, um eine Reihe von Schaltflächen in unserem zu platzieren filtersScrollView. Wie Sie im obigen Code sehen können, wird der xCoord ist die X-Position, an der eine Schaltfläche platziert wird, yCoord ist die Y-Position, buttonWidth und buttonHeight sind seine Größe und gapBetweenButtons ist der Abstand zwischen den einzelnen Tasten. 

Jetzt müssen wir die Schaltflächen tatsächlich mit a erstellen zum Schleife, die einen benutzerdefinierten kopiert UIButton und legen Sie es in die filtersScrollView basierend auf den obigen Werten. 

Platzieren Sie diesen Code direkt unter diesen CGFloat Instanzen:

 var itemCount = 0 für i in 0…  

Mal sehen, was in diesem Code passiert. Stückzahl ist eine Variable, die wir später verwenden werden, um unsere Filterschaltflächen als Unteransichten des Fensters hinzuzufügen filtersScrollView. Möglicherweise stellen Sie fest, dass wir diese Variable mit dem deklariert haben var Präfix. Das liegt daran, dass es durch das geändert wird zum Schleife. Wenn Sie Konstanten in Swift deklarieren möchten, verwenden Sie die Lassen Präfix, wie wir es für das getan haben filterButton.

Das neue verwenden zum Loop-Syntax von Swift 2.2 müssen wir nicht schreiben ich++ nicht mehr. Die Schleife wird inkrementiert ich automatisch durch Zählen von 0 bis zur Anzahl der Elemente der CIFilterNames Array.

Darin drin zum Schleife erstellen wir eine benutzerdefinierte Schaltfläche, setzen Sie ihre CGRect Werte, weisen Sie ihm ein Tag zu und fügen Sie ihm eine Zielaktion hinzu, die eine Funktion aufruft, die wir später sehen werden: filterButtonTapped ().

Damit unser Button mit runden Ecken schön aussieht, verwenden wir den Schicht und legen Sie den Eckenradius auf 6 fest. Dann schneiden Sie das Bild so ab, dass es in den Begrenzungen enthalten ist. Andernfalls würde es die abgerundeten Ecken verdecken.

Fügen Sie den Schaltflächen das Bild hinzu und wenden Sie die Filter an

Der nächste Code muss unter dem Kommentar des vorherigen eingefügt werden:

 // Erstellen Sie Filter für jede Schaltfläche. Lassen Sie ciContext = CIContext (Optionen: Keine). Lassen Sie coreImage = CIImage (Bild: originalImage.image!). Lassen Sie filter = CIFilter (Name: "\ (CIFilterNames [i])") filtern! .SetDefaults ( ) filter! .setValue (coreImage, forKey: kCIInputImageKey) Lassen Sie gefilterteImageData = filter! .valueForKey (kCIOutputImageKey) als! CIImage let gefilterteImageRef = ciContext.createCGImage (gefilterteImageData, fromRect: gefilterteImageData.extent) let imageForButton = UIImage (CGImage: gefilterteImageRef);

Hier initialisieren wir ein CIContext und CIImage Core Image funktioniert Original Bild (picture.jpg), dass jede Schaltfläche angezeigt wird. Dann initiieren wir eine Filtervariable vom Typ CIFilter das wird von jeder Taste durch die aufgerufen zum Schleife basierend auf der CIFilterNames Array.

Unsere Filter Die Instanz muss ihren Standardstatus festlegen und wird dann zur Eingabetaste für Bilder. Dann erstellen wir daraus das Datenobjekt und seine Bildreferenz, mit der wir eine erstellen UIImage sofort wird das an die Schaltfläche angehängt. 

Da die von uns für dieses Lernprogramm ausgewählten Filter von Apple vorgefertigt wurden, müssen keine zusätzlichen Werte (wie Intensität, Farbe usw.) angewendet werden. Wenn Sie Informationen über andere erhalten möchten CIFilters, Sie können die Core Image Filter Reference-Seite überprüfen.

In der letzten Zeile dieses Abschnitts legen wir schließlich das Hintergrundbild der Schaltfläche fest, das wir zuvor erstellt haben.

 // Zuweisen eines gefilterten Bildes zum Button filterButton.setBackgroundImage (imageForButton, forState: .Normal) 

Hinzufügen von Schaltflächen zum ScrollView

Nur noch ein paar Zeilen, um unsere zu vervollständigen viewDidLoad () Methode:

 // Schaltflächen in der Bildlaufansicht hinzufügen xCoord + = buttonWidth + gapBetweenButtons filtersScrollView.addSubview (filterButton) // END FOR LOOP // Bildgröße für die Bildlaufansicht filtersScrollView.contentSize = CGSizeMake (buttonWidth * CGFloat) / END viewDidload ()

Wir fügen Schaltflächen als Unteransichten zum hinzu filtersScrollView basierend auf ihrer Position und der Breite und dem Abstand, die sie untereinander beibehalten sollten. Dann schließen wir endlich die zum Schleife.

Zuletzt müssen wir das einstellen contentSize unserer ScrollView alle Knöpfe passen. Hier benutzen wir endlich die Stückzahl Variable zuvor deklariert, konvertiert in CGFloat (da CGSizeMake es akzeptiert nicht Int Werte).

Die Filter-Button-Aktion

Wir sind fast fertig mit ein paar Zeilen mehr Code!

In dem ViewController Klasse, draußen viewDidLoad (), das erstellen filterButtonTapper () Funktion. Dies wird jedes Mal aufgerufen, wenn Sie auf eine der zuvor erzeugten Schaltflächen tippen.

func filterButtonTapped (Sender: UIButton) let button = Sender als UIButton imageToFilter.image = button.backgroundImageForState (UIControlState.Normal)

Wir müssen eine Instanz von erstellen UIButton zuerst und dann die imageToFilterDieses Bild basiert auf dem Hintergrundbild dieser Schaltfläche, das bereits durch den eingefügten Code gefiltert wurde viewDidLoad ()

Stellen Sie sicher, dass die UIImageView namens imageToFilter überlagert die Original Bild, Andernfalls zeigt die App das bearbeitete Bild nicht an, da das Originalbild es verdeckt.

Speichern des verarbeiteten Bildes

Wir haben das Ende dieses Tutorials erreicht, und es gibt nur noch eine weitere Funktion, die Sie hinzufügen können .schnell Datei. Das ist der Save-Button, den wir zuvor im Storyboard platziert haben. Halt Steuerung Ziehen Sie mit der Maustaste eine blaue Linie aus der UIButton Lassen Sie die Maustaste los, und ein neues Popup-Fenster wird angezeigt. Hier muss man das ändern Verbindung tippen Sie auf Aktion und geben Sie den Namen Ihrer Methode ein - in diesem Fall savePicButton-und klicken Sie auf die Verbinden Taste.

Sie haben ein erstellt IBAction Diesmal, und hier ist der Code, der eingefügt werden muss:

 // Speichern Sie das Bild in der Kamerarolle. UIImageWriteToSavedPhotosAlbum (imageToFilter.image !, nil, nil, nil). Lassen Sie alert = UIAlertView (Titel: "Filter") : "OK") alert.show () 

Die erste Zeile speichert einfach das enthaltene Bild imageToFilter direkt in der Fotobibliothek Ihres Geräts oder im iOS-Simulator. Dann schießen wir ein einfaches UIAlertView das bestätigt, dass die Operation ausgeführt wurde.

OK, lass uns unsere App ausführen und sehen, was passiert, wenn wir unten auf die Schaltflächen tippen. Wenn Sie alles richtig gemacht haben, sollte Ihre App so aussehen:



Danke fürs Lesen und bis zum nächsten Mal! In unseren anderen Tutorials zur Swift- und iOS-App-Entwicklung finden Sie weitere Informationen.