Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 47 additions & 6 deletions Example/SnapSliderFilters/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import UIKit
import SnapSliderFilters
import MobileCoreServices

class ViewController: UIViewController {

Expand All @@ -19,7 +20,7 @@ class ViewController: UIViewController {
fileprivate let buttonSave = SNButton(frame: CGRect(x: 20, y: SNUtils.screenSize.height - 35, width: 33, height: 30), withImageNamed: "saveButton")
fileprivate let buttonCamera = SNButton(frame: CGRect(x: 75, y: SNUtils.screenSize.height - 42, width: 45, height: 45), withImageNamed: "galleryButton")
fileprivate let imagePicker = UIImagePickerController()
fileprivate var data:[SNFilter] = []
fileprivate var data:[Any] = []

//MARK: Overriden functions
override func viewDidLoad() {
Expand Down Expand Up @@ -90,6 +91,7 @@ class ViewController: UIViewController {

if let tmpImagePicker = weakSelf?.imagePicker {
tmpImagePicker.allowsEditing = false
tmpImagePicker.mediaTypes = [kUTTypeMovie as String, kUTTypeImage as String ]
tmpImagePicker.sourceType = .photoLibrary

weakSelf?.present(tmpImagePicker, animated: true, completion: nil)
Expand All @@ -104,15 +106,49 @@ class ViewController: UIViewController {
fileprivate func createData(_ image: UIImage) {
self.data = SNFilter.generateFilters(SNFilter(frame: self.slider.frame, withImage: image), filters: SNFilter.filterNameList)

self.data[1].addSticker(SNSticker(frame: CGRect(x: 195, y: 30, width: 90, height: 90), image: UIImage(named: "stick2")!))
self.data[2].addSticker(SNSticker(frame: CGRect(x: 30, y: 100, width: 250, height: 250), image: UIImage(named: "stick3")!))
self.data[3].addSticker(SNSticker(frame: CGRect(x: 20, y: 00, width: 140, height: 140), image: UIImage(named: "stick")!))
let stickers = [
SNSticker(frame: CGRect(x: 195, y: 30, width: 90, height: 90), image: UIImage(named: "stick2")!),
SNSticker(frame: CGRect(x: 30, y: 100, width: 250, height: 250), image: UIImage(named: "stick3")!),
SNSticker(frame: CGRect(x: 20, y: 00, width: 140, height: 140), image: UIImage(named: "stick")!)
]

var i = 0
while i <= data.count {
if let filter = data[i] as? SNFilter {
filter.addSticker(stickers[i % stickers.count])
}
i = i + 1
}
}

fileprivate func createData(withVideo video: NSURL) {
// Little awkward as the picker gives us an NSURL, but easy to convert to URL.
self.data = SNVideoFilter.generateFilters(SNVideoFilter(frame: self.slider.frame, withVideoAt: video as URL), filters: SNFilter.filterNameList)

let stickers = [
SNSticker(frame: CGRect(x: 195, y: 30, width: 90, height: 90), image: UIImage(named: "stick2")!),
SNSticker(frame: CGRect(x: 30, y: 100, width: 250, height: 250), image: UIImage(named: "stick3")!),
SNSticker(frame: CGRect(x: 20, y: 00, width: 140, height: 140), image: UIImage(named: "stick")!)
]

var i = 0
while i <= data.count {
if let filter = data[i] as? SNVideoFilter {
filter.addSticker(stickers[i % stickers.count])
}
i = i + 1
}
}

fileprivate func updatePicture(_ newImage: UIImage) {
createData(newImage)
slider.reloadData()
}

fileprivate func updateVideo(_ newVideoLocation: NSURL) {
createData(withVideo: newVideoLocation)
slider.reloadData()
}
}

//MARK: - Extension SNSlider DataSource
Expand All @@ -124,8 +160,7 @@ extension ViewController: SNSliderDataSource {
}

func slider(_ slider: SNSlider, slideAtIndex index: Int) -> SNFilter {

return data[index]
return data[index] as! SNFilter
}

func startAtIndex(_ slider: SNSlider) -> Int {
Expand All @@ -147,6 +182,11 @@ extension ViewController: UIGestureRecognizerDelegate {
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let movieURL = info[UIImagePickerControllerMediaURL] as? NSURL {

// The user has selected a video
updateVideo(movieURL)
}

if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {

Expand All @@ -156,6 +196,7 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControlle
updatePicture(image)
}
}


dismiss(animated: true, completion: nil)
}
Expand Down
119 changes: 119 additions & 0 deletions SnapSliderFilters/Classes/SNVideoFilter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
//
// SNVideoFilter.swift
// Pods-SnapSliderFilters_Example
//
// Created by Josh Guffey on 8/29/18.
//

import UIKit
import AVKit

open class SNVideoFilter: UIView {
var videoLocation: URL?
var currentVideoPlayer: AVPlayer?
var videoPlayerObserver: NSObjectProtocol?
var stickers = [SNSticker]()
open var filterName: String?

/*
Todo:
- Create Masking methods
- Fill out applyFilter method
- Create addSticker method
- Apply Stickers
- Test in app.
- Update SNSliderDataSource's slider sliderAtIndex method to accept videos.
*/

public override init(frame: CGRect) {
super.init(frame: frame)
}

public init(frame: CGRect, withVideoAt url:URL, withContentMode mode:UIViewContentMode = .scaleAspectFill) {
super.init(frame: frame)
self.videoLocation = url
self.contentMode = mode
self.clipsToBounds = true
let maskLayer = CAShapeLayer()
self.layer.mask = maskLayer
maskLayer.frame = frame
}

required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

open static func generateFilters(_ originalVideo: SNVideoFilter, filters:[String]) -> [SNVideoFilter] {
var finalFilters = [SNVideoFilter]()

for filter in filters {
let filterComputed = originalVideo.applyFilter(filterNamed: filter)
finalFilters.append(filterComputed)
}

return finalFilters
}

open func addSticker(_ sticker: SNSticker) {
self.stickers.append(sticker)
}

// MARK: - Video Specific
func setupNonSliderView() {
// Load in the video, and add a sublayer to play the video.
if let url = self.videoLocation {
let player = AVPlayer(url: url)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.backgroundColor = UIColor.clear.cgColor
playerLayer.frame = self.bounds
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
self.layer.sublayers?
.filter { $0 is AVPlayerLayer }
.forEach { $0.removeFromSuperlayer() }
self.layer.addSublayer(playerLayer)

// Configure the player.
player.play()
player.allowsExternalPlayback = false

// Configure the video to loop.
self.videoPlayerObserver = NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: player.currentItem, queue: .main) { (_) in
player.seek(to: kCMTimeZero)
player.play()
}

// Store player for later use
self.currentVideoPlayer = player
}
}

// MARK: - Video Filtering
func applyFilter(filterNamed name: String) -> SNVideoFilter {
let filter:SNVideoFilter = self.copy() as! SNVideoFilter
// Load the video
// Apply the filtering to the video.
// Return the new video.
return filter
}

}

// MARK: - NSCopying protocol

extension SNVideoFilter: NSCopying {

public func copy(with zone: NSZone?) -> Any {
guard
let videoLocation = videoLocation
else { fatalError("The video location is mandatory") }

let copy = SNVideoFilter(frame: frame, withVideoAt: videoLocation, withContentMode: contentMode)
copy.backgroundColor = self.backgroundColor
copy.filterName = filterName

for s in stickers {
copy.stickers.append(s.copy() as! SNSticker)
}
return copy
}
}