From 08d1c0d1afc4106615ce40fa93a38e1ef4529d68 Mon Sep 17 00:00:00 2001 From: Kenneth Jones Date: Mon, 9 Nov 2020 16:42:03 -0700 Subject: [PATCH 1/3] Added photo filter design elements to Storyboard and View Controller --- LambdaTimeline/Storyboards/Main.storyboard | 228 ++++++++++++++---- .../ImagePostViewController.swift | 80 +++++- 2 files changed, 260 insertions(+), 48 deletions(-) diff --git a/LambdaTimeline/Storyboards/Main.storyboard b/LambdaTimeline/Storyboards/Main.storyboard index 9e2d25d6..88c74a73 100644 --- a/LambdaTimeline/Storyboards/Main.storyboard +++ b/LambdaTimeline/Storyboards/Main.storyboard @@ -1,10 +1,11 @@ - - + + - + + @@ -13,9 +14,9 @@ - + - + @@ -24,7 +25,7 @@ - + @@ -34,19 +35,19 @@ - + - + - + + + + diff --git a/LambdaTimeline/View Controllers/ImagePostViewController.swift b/LambdaTimeline/View Controllers/ImagePostViewController.swift index 9cffbbbb..c7366ed9 100644 --- a/LambdaTimeline/View Controllers/ImagePostViewController.swift +++ b/LambdaTimeline/View Controllers/ImagePostViewController.swift @@ -17,6 +17,20 @@ class ImagePostViewController: ShiftableViewController { @IBOutlet weak var imageHeightConstraint: NSLayoutConstraint! @IBOutlet weak var postButton: UIBarButtonItem! + @IBOutlet weak var addFilterLabel: UILabel! + @IBOutlet weak var clearFiltersButton: UIButton! + @IBOutlet weak var toneButton: UIButton! + @IBOutlet weak var vintageButton: UIButton! + @IBOutlet weak var noirButton: UIButton! + @IBOutlet weak var tweakLabel: UILabel! + @IBOutlet weak var exposureLabel: UILabel! + @IBOutlet weak var exposureSlider: UISlider! + @IBOutlet weak var vibranceLabel: UILabel! + @IBOutlet weak var vibranceSlider: UISlider! + @IBOutlet weak var posterizeLabel: UILabel! + @IBOutlet weak var posterizeSlider: UISlider! + + var postController: PostController! var post: Post? var imageData: Data? @@ -25,6 +39,19 @@ class ImagePostViewController: ShiftableViewController { super.viewDidLoad() setImageViewHeight(with: 1.0) + + addFilterLabel.isHidden = true + clearFiltersButton.isHidden = true + toneButton.isHidden = true + vintageButton.isHidden = true + noirButton.isHidden = true + tweakLabel.isHidden = true + exposureLabel.isHidden = true + exposureSlider.isHidden = true + vibranceLabel.isHidden = true + vibranceSlider.isHidden = true + posterizeLabel.isHidden = true + posterizeSlider.isHidden = true } private func presentImagePickerController() { @@ -34,11 +61,13 @@ class ImagePostViewController: ShiftableViewController { return } - let imagePicker = UIImagePickerController() - imagePicker.delegate = self - imagePicker.sourceType = .photoLibrary - - present(imagePicker, animated: true, completion: nil) + DispatchQueue.main.async { + let imagePicker = UIImagePickerController() + imagePicker.delegate = self + imagePicker.sourceType = .photoLibrary + + self.present(imagePicker, animated: true, completion: nil) + } } @IBAction func createPost(_ sender: Any) { @@ -96,6 +125,34 @@ class ImagePostViewController: ShiftableViewController { view.layoutSubviews() } + + @IBAction func clearFilters(_ sender: Any) { + + } + + @IBAction func addToneFilter(_ sender: Any) { + + } + + @IBAction func addVintageFilter(_ sender: Any) { + + } + + @IBAction func addNoirFilter(_ sender: Any) { + + } + + @IBAction func expoureChanged(_ sender: Any) { + + } + + @IBAction func vibranceChanged(_ sender: Any) { + + } + + @IBAction func posterizeChanged(_ sender: Any) { + + } } extension ImagePostViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { @@ -111,6 +168,19 @@ extension ImagePostViewController: UIImagePickerControllerDelegate, UINavigation imageView.image = image setImageViewHeight(with: image.ratio) + + addFilterLabel.isHidden = false + clearFiltersButton.isHidden = false + toneButton.isHidden = false + vintageButton.isHidden = false + noirButton.isHidden = false + tweakLabel.isHidden = false + exposureLabel.isHidden = false + exposureSlider.isHidden = false + vibranceLabel.isHidden = false + vibranceSlider.isHidden = false + posterizeLabel.isHidden = false + posterizeSlider.isHidden = false } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { From fb0b61c935e1aa681f8da257a09b914619eb0bf4 Mon Sep 17 00:00:00 2001 From: Kenneth Jones Date: Mon, 9 Nov 2020 19:35:59 -0700 Subject: [PATCH 2/3] Added filters --- .../Helpers/Extensions/UIImage+Ratio.swift | 26 +++++ LambdaTimeline/Storyboards/Main.storyboard | 4 +- .../ImagePostViewController.swift | 103 ++++++++++++++++-- 3 files changed, 124 insertions(+), 9 deletions(-) diff --git a/LambdaTimeline/Helpers/Extensions/UIImage+Ratio.swift b/LambdaTimeline/Helpers/Extensions/UIImage+Ratio.swift index 79bb32d7..d3133b5e 100644 --- a/LambdaTimeline/Helpers/Extensions/UIImage+Ratio.swift +++ b/LambdaTimeline/Helpers/Extensions/UIImage+Ratio.swift @@ -12,4 +12,30 @@ extension UIImage { var ratio: CGFloat { return size.height / size.width } + + /// Resize the image to a max dimension from size parameter + func imageByScaling(toSize size: CGSize) -> UIImage? { + guard size.width > 0 && size.height > 0 else { return nil } + + let originalAspectRatio = self.size.width/self.size.height + var correctedSize = size + + if correctedSize.width > correctedSize.width*originalAspectRatio { + correctedSize.width = correctedSize.width*originalAspectRatio + } else { + correctedSize.height = correctedSize.height/originalAspectRatio + } + + return UIGraphicsImageRenderer(size: correctedSize, format: imageRendererFormat).image { context in + draw(in: CGRect(origin: .zero, size: correctedSize)) + } + } + + /// Renders the image if the pixel data was rotated due to orientation of camera + var flattened: UIImage { + if imageOrientation == .up { return self } + return UIGraphicsImageRenderer(size: size, format: imageRendererFormat).image { context in + draw(at: .zero) + } + } } diff --git a/LambdaTimeline/Storyboards/Main.storyboard b/LambdaTimeline/Storyboards/Main.storyboard index 88c74a73..6ea44915 100644 --- a/LambdaTimeline/Storyboards/Main.storyboard +++ b/LambdaTimeline/Storyboards/Main.storyboard @@ -241,13 +241,13 @@ - + - + diff --git a/LambdaTimeline/View Controllers/ImagePostViewController.swift b/LambdaTimeline/View Controllers/ImagePostViewController.swift index c7366ed9..f41237d8 100644 --- a/LambdaTimeline/View Controllers/ImagePostViewController.swift +++ b/LambdaTimeline/View Controllers/ImagePostViewController.swift @@ -7,6 +7,8 @@ // import UIKit +import CoreImage +import CoreImage.CIFilterBuiltins import Photos class ImagePostViewController: ShiftableViewController { @@ -30,10 +32,46 @@ class ImagePostViewController: ShiftableViewController { @IBOutlet weak var posterizeLabel: UILabel! @IBOutlet weak var posterizeSlider: UISlider! + private let context = CIContext() + private let toneFilter = CIFilter.sRGBToneCurveToLinear() + private let vintageFilter = CIFilter.photoEffectInstant() + private let noirFilter = CIFilter.photoEffectNoir() + private let exposureFilter = CIFilter.exposureAdjust() + private let vibranceFilter = CIFilter.vibrance() + private let posterizeFilter = CIFilter.colorPosterize() var postController: PostController! var post: Post? var imageData: Data? + var selectedFilter: CIFilter? + + var originalImage: UIImage? { + didSet { + guard let originalImage = originalImage else { + scaledImage = nil + return + } + + var scaledSize = imageView.bounds.size + let scale = imageView.contentScaleFactor + + scaledSize.width *= scale + scaledSize.height *= scale + + guard let scaledUIImage = originalImage.imageByScaling(toSize: scaledSize) else { + scaledImage = nil + return + } + + scaledImage = CIImage(image: scaledUIImage) + } + } + + var scaledImage: CIImage? { + didSet { + updateImage() + } + } override func viewDidLoad() { super.viewDidLoad() @@ -70,6 +108,44 @@ class ImagePostViewController: ShiftableViewController { } } + private func image(byFiltering inputImage: CIImage, withFilter inputFilter: CIFilter?) -> UIImage? { + var output = inputImage + + if inputFilter == toneFilter { + toneFilter.inputImage = inputImage + output = toneFilter.outputImage! + } else if inputFilter == vintageFilter { + vintageFilter.inputImage = inputImage + output = vintageFilter.outputImage! + } else if inputFilter == noirFilter { + noirFilter.inputImage = inputImage + output = noirFilter.outputImage! + } + + exposureFilter.inputImage = output + exposureFilter.ev = exposureSlider.value + + vibranceFilter.inputImage = exposureFilter.outputImage + vibranceFilter.amount = vibranceSlider.value + + posterizeFilter.inputImage = vibranceFilter.outputImage + posterizeFilter.levels = posterizeSlider.value + + guard let outputImage = posterizeFilter.outputImage else { return nil } + + guard let renderedCGImage = context.createCGImage(outputImage, from: inputImage.extent) else { return nil } + + return UIImage(cgImage: renderedCGImage) + } + + private func updateImage() { + if let scaledImage = scaledImage { + imageView.image = image(byFiltering: scaledImage, withFilter: selectedFilter) + } else { + imageView.image = nil + } + } + @IBAction func createPost(_ sender: Any) { view.endEditing(true) @@ -127,31 +203,38 @@ class ImagePostViewController: ShiftableViewController { } @IBAction func clearFilters(_ sender: Any) { - + selectedFilter = nil + exposureSlider.value = 0.5 + vibranceSlider.value = 0 + posterizeSlider.value = 50 + updateImage() } @IBAction func addToneFilter(_ sender: Any) { - + selectedFilter = toneFilter + updateImage() } @IBAction func addVintageFilter(_ sender: Any) { - + selectedFilter = vintageFilter + updateImage() } @IBAction func addNoirFilter(_ sender: Any) { - + selectedFilter = noirFilter + updateImage() } @IBAction func expoureChanged(_ sender: Any) { - + updateImage() } @IBAction func vibranceChanged(_ sender: Any) { - + updateImage() } @IBAction func posterizeChanged(_ sender: Any) { - + updateImage() } } @@ -181,6 +264,12 @@ extension ImagePostViewController: UIImagePickerControllerDelegate, UINavigation vibranceSlider.isHidden = false posterizeLabel.isHidden = false posterizeSlider.isHidden = false + + exposureSlider.value = 0.5 + vibranceSlider.value = 0 + posterizeSlider.value = 50 + + originalImage = imageView.image } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { From ca4ec81eb0583119d477b640d0b319d8594c5e37 Mon Sep 17 00:00:00 2001 From: Kenneth Jones Date: Mon, 9 Nov 2020 20:10:58 -0700 Subject: [PATCH 3/3] Fixed ability to add comments; completed project --- LambdaTimeline/Model Controllers/PostController.swift | 1 - LambdaTimeline/Storyboards/Main.storyboard | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/LambdaTimeline/Model Controllers/PostController.swift b/LambdaTimeline/Model Controllers/PostController.swift index 3df87148..7d07224c 100644 --- a/LambdaTimeline/Model Controllers/PostController.swift +++ b/LambdaTimeline/Model Controllers/PostController.swift @@ -31,6 +31,5 @@ class PostController { let comment = Comment(text: text, author: currentUser) post.comments.append(comment) - } } diff --git a/LambdaTimeline/Storyboards/Main.storyboard b/LambdaTimeline/Storyboards/Main.storyboard index 6ea44915..8294f4b9 100644 --- a/LambdaTimeline/Storyboards/Main.storyboard +++ b/LambdaTimeline/Storyboards/Main.storyboard @@ -459,7 +459,7 @@ - +