Disk+UIImage.swift 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import Foundation
  2. import UIKit
  3. public extension Disk {
  4. /// Save image to disk
  5. ///
  6. /// - Parameters:
  7. /// - value: image to store to disk
  8. /// - directory: user directory to store the image file in
  9. /// - path: file location to store the data (i.e. "Folder/file.png")
  10. /// - Throws: Error if there were any issues writing the image to disk
  11. static func save(_ value: UIImage, to directory: Directory, as path: String) throws {
  12. do {
  13. var imageData: Data
  14. if path.suffix(4).lowercased() == ".png" {
  15. let pngData: Data?
  16. #if swift(>=4.2)
  17. pngData = value.pngData()
  18. #else
  19. pngData = UIImagePNGRepresentation(value)
  20. #endif
  21. if let data = pngData {
  22. imageData = data
  23. } else {
  24. throw createError(
  25. .serialization,
  26. description: "Could not serialize UIImage to PNG.",
  27. failureReason: "Data conversion failed.",
  28. recoverySuggestion: "Try saving this image as a .jpg or without an extension at all."
  29. )
  30. }
  31. } else if path.suffix(4).lowercased() == ".jpg" || path.suffix(5).lowercased() == ".jpeg" {
  32. let jpegData: Data?
  33. #if swift(>=4.2)
  34. jpegData = value.jpegData(compressionQuality: 1)
  35. #else
  36. jpegData = UIImageJPEGRepresentation(value, 1)
  37. #endif
  38. if let data = jpegData {
  39. imageData = data
  40. } else {
  41. throw createError(
  42. .serialization,
  43. description: "Could not serialize UIImage to JPEG.",
  44. failureReason: "Data conversion failed.",
  45. recoverySuggestion: "Try saving this image as a .png or without an extension at all."
  46. )
  47. }
  48. } else {
  49. var data: Data?
  50. #if swift(>=4.2)
  51. if let pngData = value.pngData() {
  52. data = pngData
  53. } else if let jpegData = value.jpegData(compressionQuality: 1) {
  54. data = jpegData
  55. }
  56. #else
  57. if let pngData = UIImagePNGRepresentation(value) {
  58. data = pngData
  59. } else if let jpegData = UIImageJPEGRepresentation(value, 1) {
  60. data = jpegData
  61. }
  62. #endif
  63. if let data = data {
  64. imageData = data
  65. } else {
  66. throw createError(
  67. .serialization,
  68. description: "Could not serialize UIImage to Data.",
  69. failureReason: "UIImage could not serialize to PNG or JPEG data.",
  70. recoverySuggestion: "Make sure image is not corrupt or try saving without an extension at all."
  71. )
  72. }
  73. }
  74. let url = try createURL(for: path, in: directory)
  75. try createSubfoldersBeforeCreatingFile(at: url)
  76. try imageData.write(to: url, options: .atomic)
  77. } catch {
  78. throw error
  79. }
  80. }
  81. /// Retrieve image from disk
  82. ///
  83. /// - Parameters:
  84. /// - path: path where image is stored
  85. /// - directory: user directory to retrieve the image file from
  86. /// - type: here for Swifty generics magic, use UIImage.self
  87. /// - Returns: UIImage from disk
  88. /// - Throws: Error if there were any issues retrieving the specified image
  89. static func retrieve(_ path: String, from directory: Directory, as _: UIImage.Type) throws -> UIImage {
  90. do {
  91. let url = try getExistingFileURL(for: path, in: directory)
  92. let data = try Data(contentsOf: url)
  93. if let image = UIImage(data: data) {
  94. return image
  95. } else {
  96. throw createError(
  97. .deserialization,
  98. description: "Could not decode UIImage from \(url.path).",
  99. failureReason: "A UIImage could not be created out of the data in \(url.path).",
  100. recoverySuggestion: "Try deserializing \(url.path) manually after retrieving it as Data."
  101. )
  102. }
  103. } catch {
  104. throw error
  105. }
  106. }
  107. }