CameraExtensions.swift 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import UIKit
  2. import Photos
  3. internal protocol CameraAuthorizationState {
  4. var authorizationState: String { get }
  5. }
  6. extension AVAuthorizationStatus: CameraAuthorizationState {
  7. var authorizationState: String {
  8. switch self {
  9. case .denied, .restricted:
  10. return "denied"
  11. case .authorized:
  12. return "granted"
  13. case .notDetermined:
  14. fallthrough
  15. @unknown default:
  16. return "prompt"
  17. }
  18. }
  19. }
  20. extension PHAuthorizationStatus: CameraAuthorizationState {
  21. var authorizationState: String {
  22. switch self {
  23. case .denied, .restricted:
  24. return "denied"
  25. case .authorized:
  26. return "granted"
  27. case .limited:
  28. return "limited"
  29. case .notDetermined:
  30. fallthrough
  31. @unknown default:
  32. return "prompt"
  33. }
  34. }
  35. }
  36. internal extension PHAsset {
  37. /**
  38. Retrieves the image metadata for the asset.
  39. */
  40. var imageData: [String: Any] {
  41. let options = PHImageRequestOptions()
  42. options.isSynchronous = true
  43. options.resizeMode = .none
  44. options.isNetworkAccessAllowed = false
  45. options.version = .current
  46. var result: [String: Any] = [:]
  47. _ = PHCachingImageManager().requestImageDataAndOrientation(for: self, options: options) { (data, _, _, _) in
  48. if let data = data as NSData? {
  49. let options = [kCGImageSourceShouldCache as String: kCFBooleanFalse] as CFDictionary
  50. if let imgSrc = CGImageSourceCreateWithData(data, options),
  51. let metadata = CGImageSourceCopyPropertiesAtIndex(imgSrc, 0, options) as? [String: Any] {
  52. result = metadata
  53. }
  54. }
  55. }
  56. return result
  57. }
  58. }
  59. internal extension UIImage {
  60. /**
  61. Generates a new image from the existing one, implicitly resetting any orientation.
  62. Dimensions greater than 0 will resize the image while preserving the aspect ratio.
  63. */
  64. func reformat(to size: CGSize? = nil) -> UIImage {
  65. let imageHeight = self.size.height
  66. let imageWidth = self.size.width
  67. // determine the max dimensions, 0 is treated as 'no restriction'
  68. var maxWidth: CGFloat
  69. if let size = size, size.width > 0 {
  70. maxWidth = size.width
  71. } else {
  72. maxWidth = imageWidth
  73. }
  74. let maxHeight: CGFloat
  75. if let size = size, size.height > 0 {
  76. maxHeight = size.height
  77. } else {
  78. maxHeight = imageHeight
  79. }
  80. // adjust to preserve aspect ratio
  81. var targetWidth = min(imageWidth, maxWidth)
  82. var targetHeight = (imageHeight * targetWidth) / imageWidth
  83. if targetHeight > maxHeight {
  84. targetWidth = (imageWidth * maxHeight) / imageHeight
  85. targetHeight = maxHeight
  86. }
  87. // generate the new image and return
  88. UIGraphicsBeginImageContextWithOptions(.init(width: targetWidth, height: targetHeight), false, 1.0) // size, opaque and scale
  89. self.draw(in: .init(origin: .zero, size: .init(width: targetWidth, height: targetHeight)))
  90. let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
  91. UIGraphicsEndImageContext()
  92. return resizedImage ?? self
  93. }
  94. }