From 70ea803a49e1329f44519fe4cac4f6e718787d4b Mon Sep 17 00:00:00 2001 From: JRoberts <8711996+jr-simplex@users.noreply.github.com> Date: Wed, 4 May 2022 16:08:40 +0400 Subject: [PATCH] ios: move image utils to FileUtils (#598) --- apps/ios/Shared/FileUtils.swift | 75 +++++++++++++++++++ .../Shared/Views/Helpers/ImagePicker.swift | 74 ------------------ 2 files changed, 75 insertions(+), 74 deletions(-) diff --git a/apps/ios/Shared/FileUtils.swift b/apps/ios/Shared/FileUtils.swift index e6cf6fa140..b3346293a8 100644 --- a/apps/ios/Shared/FileUtils.swift +++ b/apps/ios/Shared/FileUtils.swift @@ -37,3 +37,78 @@ func getStoredImage(_ file: CIFile?) -> UIImage? { } return nil } + +// image utils + +func dropImagePrefix(_ s: String) -> String { + dropPrefix(dropPrefix(s, "data:image/png;base64,"), "data:image/jpg;base64,") +} + +private func dropPrefix(_ s: String, _ prefix: String) -> String { + s.hasPrefix(prefix) ? String(s.dropFirst(prefix.count)) : s +} + +func cropToSquare(_ image: UIImage) -> UIImage { + let size = image.size + let side = min(size.width, size.height) + let newSize = CGSize(width: side, height: side) + var origin = CGPoint.zero + if size.width > side { + origin.x -= (size.width - side) / 2 + } else if size.height > side { + origin.y -= (size.height - side) / 2 + } + return resizeImage(image, newBounds: CGRect(origin: .zero, size: newSize), drawIn: CGRect(origin: origin, size: size)) +} + +func resizeImageToDataSize(_ image: UIImage, maxDataSize: Int) -> Data? { + var img = image + var data = img.jpegData(compressionQuality: 0.85) + var dataSize = data?.count ?? 0 + while dataSize != 0 && dataSize > maxDataSize { + let ratio = sqrt(Double(dataSize) / Double(maxDataSize)) + let clippedRatio = min(ratio, 2.0) + img = reduceSize(img, ratio: clippedRatio) + data = img.jpegData(compressionQuality: 0.85) + dataSize = data?.count ?? 0 + } + logger.debug("resizeImageToDataSize final \(dataSize)") + return data +} + +func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int) -> String? { + var img = image + var str = compressImageStr(img) + var dataSize = str?.count ?? 0 + while dataSize != 0 && dataSize > maxDataSize { + let ratio = sqrt(Double(dataSize) / Double(maxDataSize)) + let clippedRatio = min(ratio, 2.0) + img = reduceSize(img, ratio: clippedRatio) + str = compressImageStr(img) + dataSize = str?.count ?? 0 + } + logger.debug("resizeImageToStrSize final \(dataSize)") + return str +} + +func compressImageStr(_ image: UIImage, _ compressionQuality: CGFloat = 0.85) -> String? { + if let data = image.jpegData(compressionQuality: compressionQuality) { + return "data:image/jpg;base64,\(data.base64EncodedString())" + } + return nil +} + +private func reduceSize(_ image: UIImage, ratio: CGFloat) -> UIImage { + let newSize = CGSize(width: floor(image.size.width / ratio), height: floor(image.size.height / ratio)) + let bounds = CGRect(origin: .zero, size: newSize) + return resizeImage(image, newBounds: bounds, drawIn: bounds) +} + +private func resizeImage(_ image: UIImage, newBounds: CGRect, drawIn: CGRect) -> UIImage { + let format = UIGraphicsImageRendererFormat() + format.scale = 1.0 + format.opaque = true + return UIGraphicsImageRenderer(bounds: newBounds, format: format).image { _ in + image.draw(in: drawIn) + } +} diff --git a/apps/ios/Shared/Views/Helpers/ImagePicker.swift b/apps/ios/Shared/Views/Helpers/ImagePicker.swift index 06c4825c6a..8c2b68b8bc 100644 --- a/apps/ios/Shared/Views/Helpers/ImagePicker.swift +++ b/apps/ios/Shared/Views/Helpers/ImagePicker.swift @@ -9,80 +9,6 @@ import SwiftUI import PhotosUI -func dropPrefix(_ s: String, _ prefix: String) -> String { - s.hasPrefix(prefix) ? String(s.dropFirst(prefix.count)) : s -} - -func dropImagePrefix(_ s: String) -> String { - dropPrefix(dropPrefix(s, "data:image/png;base64,"), "data:image/jpg;base64,") -} - -private func resizeImage(_ image: UIImage, newBounds: CGRect, drawIn: CGRect) -> UIImage { - let format = UIGraphicsImageRendererFormat() - format.scale = 1.0 - format.opaque = true - return UIGraphicsImageRenderer(bounds: newBounds, format: format).image { _ in - image.draw(in: drawIn) - } -} - -func cropToSquare(_ image: UIImage) -> UIImage { - let size = image.size - let side = min(size.width, size.height) - let newSize = CGSize(width: side, height: side) - var origin = CGPoint.zero - if size.width > side { - origin.x -= (size.width - side) / 2 - } else if size.height > side { - origin.y -= (size.height - side) / 2 - } - return resizeImage(image, newBounds: CGRect(origin: .zero, size: newSize), drawIn: CGRect(origin: origin, size: size)) -} - - -func reduceSize(_ image: UIImage, ratio: CGFloat) -> UIImage { - let newSize = CGSize(width: floor(image.size.width / ratio), height: floor(image.size.height / ratio)) - let bounds = CGRect(origin: .zero, size: newSize) - return resizeImage(image, newBounds: bounds, drawIn: bounds) -} - -func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int) -> String? { - var img = image - var str = compressImageStr(img) - var dataSize = str?.count ?? 0 - while dataSize != 0 && dataSize > maxDataSize { - let ratio = sqrt(Double(dataSize) / Double(maxDataSize)) - let clippedRatio = min(ratio, 2.0) - img = reduceSize(img, ratio: clippedRatio) - str = compressImageStr(img) - dataSize = str?.count ?? 0 - } - logger.debug("resizeImageToStrSize final \(dataSize)") - return str -} - -func compressImageStr(_ image: UIImage, _ compressionQuality: CGFloat = 0.85) -> String? { - if let data = image.jpegData(compressionQuality: compressionQuality) { - return "data:image/jpg;base64,\(data.base64EncodedString())" - } - return nil -} - -func resizeImageToDataSize(_ image: UIImage, maxDataSize: Int) -> Data? { - var img = image - var data = img.jpegData(compressionQuality: 0.85) - var dataSize = data?.count ?? 0 - while dataSize != 0 && dataSize > maxDataSize { - let ratio = sqrt(Double(dataSize) / Double(maxDataSize)) - let clippedRatio = min(ratio, 2.0) - img = reduceSize(img, ratio: clippedRatio) - data = img.jpegData(compressionQuality: 0.85) - dataSize = data?.count ?? 0 - } - logger.debug("resizeImageToDataSize final \(dataSize)") - return data -} - enum ImageSource { case imageLibrary case camera