ImagePicker.swift (5365B)
1 // 2 // ImagePicker.swift 3 // damus 4 // 5 // Created by Swift on 3/31/23. 6 // 7 8 import UIKit 9 import SwiftUI 10 11 struct ImagePicker: UIViewControllerRepresentable { 12 13 @Environment(\.presentationMode) 14 private var presentationMode 15 16 let uploader: MediaUploader 17 let sourceType: UIImagePickerController.SourceType 18 let pubkey: Pubkey 19 @Binding var image_upload_confirm: Bool 20 var imagesOnly: Bool = false 21 let onImagePicked: (URL) -> Void 22 let onVideoPicked: (URL) -> Void 23 24 final class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate { 25 @Binding private var presentationMode: PresentationMode 26 private let onImagePicked: (URL) -> Void 27 private let onVideoPicked: (URL) -> Void 28 @Binding var image_upload_confirm: Bool 29 30 init(presentationMode: Binding<PresentationMode>, 31 onImagePicked: @escaping (URL) -> Void, 32 onVideoPicked: @escaping (URL) -> Void, 33 image_upload_confirm: Binding<Bool>) { 34 _presentationMode = presentationMode 35 self.onImagePicked = onImagePicked 36 self.onVideoPicked = onVideoPicked 37 self._image_upload_confirm = image_upload_confirm 38 } 39 40 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { 41 if let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as? URL { 42 // Handle the selected video 43 onVideoPicked(videoURL) 44 } else if let imageURL = info[UIImagePickerController.InfoKey.imageURL] as? URL { 45 // Handle the selected image 46 onImagePicked(imageURL) 47 } else if let cameraImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage { 48 let orientedImage = cameraImage.fixOrientation() 49 if let imageURL = saveImageToTemporaryFolder(image: orientedImage, imageType: "jpeg") { 50 onImagePicked(imageURL) 51 } 52 } else if let editedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage { 53 let orientedImage = editedImage.fixOrientation() 54 if let editedImageURL = saveImageToTemporaryFolder(image: orientedImage, imageType: "jpeg") { 55 onImagePicked(editedImageURL) 56 } 57 } 58 image_upload_confirm = true 59 } 60 61 func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 62 presentationMode.dismiss() 63 } 64 65 func saveImageToTemporaryFolder(image: UIImage, imageType: String = "png") -> URL? { 66 // Convert UIImage to Data 67 let imageData: Data? 68 if imageType.lowercased() == "jpeg" { 69 imageData = image.jpegData(compressionQuality: 1.0) 70 } else { 71 imageData = image.pngData() 72 } 73 74 guard let data = imageData else { 75 print("Failed to convert UIImage to Data.") 76 return nil 77 } 78 79 // Generate a temporary URL with a unique filename 80 let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) 81 let uniqueImageName = "\(UUID().uuidString).\(imageType)" 82 let temporaryImageURL = temporaryDirectoryURL.appendingPathComponent(uniqueImageName) 83 84 // Save the image data to the temporary URL 85 do { 86 try data.write(to: temporaryImageURL) 87 return temporaryImageURL 88 } catch { 89 print("Error saving image data to temporary URL: \(error.localizedDescription)") 90 return nil 91 } 92 } 93 } 94 95 func makeCoordinator() -> Coordinator { 96 return Coordinator(presentationMode: presentationMode, 97 onImagePicked: { url in 98 // Handle the selected image URL 99 onImagePicked(url) 100 }, 101 onVideoPicked: { videoURL in 102 // Handle the selected video URL 103 onVideoPicked(videoURL) 104 }, image_upload_confirm: $image_upload_confirm) 105 } 106 107 func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController { 108 let picker = UIImagePickerController() 109 picker.sourceType = sourceType 110 picker.mediaTypes = ["public.image", "com.compuserve.gif"] 111 if uploader.supportsVideo && !imagesOnly { 112 picker.mediaTypes.append("public.movie") 113 } 114 picker.delegate = context.coordinator 115 return picker 116 } 117 118 func updateUIViewController(_ uiViewController: UIImagePickerController, 119 context: UIViewControllerRepresentableContext<ImagePicker>) { 120 121 } 122 } 123 124 extension UIImage { 125 func fixOrientation() -> UIImage { 126 guard imageOrientation != .up else { return self } 127 128 UIGraphicsBeginImageContextWithOptions(size, false, scale) 129 draw(in: CGRect(origin: .zero, size: size)) 130 let normalizedImage = UIGraphicsGetImageFromCurrentImageContext() 131 UIGraphicsEndImageContext() 132 133 return normalizedImage ?? self 134 } 135 }