Skip to content

Instantly share code, notes, and snippets.

@egzonpllana
Last active December 20, 2019 07:08
Show Gist options
  • Save egzonpllana/132b8dc67f31c8bafabf529977eafe15 to your computer and use it in GitHub Desktop.
Save egzonpllana/132b8dc67f31c8bafabf529977eafe15 to your computer and use it in GitHub Desktop.
//
// MediaPicker.swift
// DeveloperBelt
//
// Created by Egzon Pllana on 11/5/19.
// Copyright © 2019 Native Coders. All rights reserved.
//
/* Info.plist
Privacy - Camera Usage Description
Privacy - Photo Library Usage Description
Privacy - Microphone Usage Description
*/
import UIKit
import AVFoundation
import MobileCoreServices
class MediaPicker: UIViewController {
// MARK: - Outlets
@IBOutlet weak var imagePreview: UIImageView!
// MARK: - Properties
var choosenImageData: Data? {
didSet {
if let imageData = choosenImageData {
imagePreview.image = UIImage(data: imageData)
} else {
print("Image coversion failed!", #line, #function)
}
}
}
var choosenVideoPath: URL? {
didSet {
imagePreview.image = generateThumbnail(path: choosenVideoPath)
}
}
// MARK: - Lazy Properties
fileprivate lazy var imagePicker: UIImagePickerController = {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.mediaTypes = [(kUTTypeImage as String)]
imagePicker.allowsEditing = true
return imagePicker
}()
fileprivate lazy var videoPicker: UIImagePickerController = {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.mediaTypes = [(kUTTypeMovie as String)]
imagePicker.allowsEditing = true
return imagePicker
}()
// MARK: - View life cycle
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
// MARK: - Functions
private func presentProfileActionController(title: String, message: String?) {
// https://www.ioscreator.com/tutorials/record-video-ios-tutorial
let actionSheet =
UIAlertController(title: title,
message: message,
preferredStyle: .actionSheet)
actionSheet.addAction(
UIAlertAction(title: "Image from gallery", style: .default, handler: { (_: UIAlertAction) in
self.imagePicker.sourceType = .photoLibrary
self.present(self.imagePicker, animated: true, completion: nil)
}))
actionSheet.addAction(
UIAlertAction(title: "Video from gallery", style: .default, handler: { (_: UIAlertAction) in
self.videoPicker.sourceType = .photoLibrary
self.present(self.videoPicker, animated: true, completion: nil)
}))
if UIImagePickerController.isSourceTypeAvailable(.camera) {
actionSheet.addAction(
UIAlertAction(title: "Take a photo", style: .default, handler: { (_: UIAlertAction) in
self.imagePicker.sourceType = .camera
self.present(self.imagePicker, animated: true, completion: nil)
}))
actionSheet.addAction(
UIAlertAction(title: "Record a video", style: .default, handler: { (_: UIAlertAction) in
self.videoPicker.sourceType = .camera
self.present(self.videoPicker, animated: true, completion: nil)
}))
}
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
private func generateThumbnail(path: URL?) -> UIImage? {
guard let path = path else {
print("Empty video path! -> ", #line, #function)
return nil
}
// https://stackoverflow.com/a/40987452/7987502
do {
let asset = AVURLAsset(url: path, options: nil)
let imgGenerator = AVAssetImageGenerator(asset: asset)
imgGenerator.appliesPreferredTrackTransform = true
let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil)
let thumbnail = UIImage(cgImage: cgImage)
return thumbnail
} catch let error {
print("*** Error generating thumbnail: \(error.localizedDescription)")
return nil
}
}
}
// ImagePickerControllerDelegate, NavigationControllerDelegate
extension MediaPicker: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
defer {
picker.dismiss(animated: true)
}
if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
self.choosenImageData = image.jpeg(.lowest)
} else if let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as? NSURL {
self.choosenVideoPath = videoURL as URL
}
}
}
// Compress UIImage Quality
extension UIImage {
enum JPEGQuality: CGFloat {
case lowest = 0
case low = 0.25
case medium = 0.5
case high = 0.75
case highest = 1
}
/// Returns the data for the specified image in JPEG format.
/// If the image object’s underlying image data has been purged, calling this function forces that data to be reloaded into memory.
/// - returns: A data object containing the JPEG data, or nil if there was a problem generating the data. This function may return nil if the image has no data or if the underlying CGImageRef contains data in an unsupported bitmap format.
func jpeg(_ quality: JPEGQuality) -> Data? {
return self.jpegData(compressionQuality: quality.rawValue)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment