SwiftUI: Is it possible to let the user scale an image chosen with PHpicker?

1.2k Views Asked by At

I have an image picker created with PHPicker, and I was wondering if it is possible to let the user scale the chosen image?

This is not the entire code, but just the code for the makeUIViewController which I think is what is needed to solve this problem. I can of course provide the rest of the code if necessary.

This is what I'm looking for enter image description here

   func makeUIViewController(context: Context) -> PHPickerViewController {
        var config = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
        config.filter = .images
        config.selectionLimit = 1
        
        let controller = PHPickerViewController(configuration: config)
        controller.delegate = context.coordinator
        return controller
    }
    
1

There are 1 best solutions below

12
On

can use this one line after choose the image to fixed height and width of your image

Image(room.thumbnailImage)
    .resizable()
    .frame(width: 32.0, height: 32.0)

or here i am sharing my running work with you checkout function didFinishPicking and var body: some View

import SwiftUI
import PhotosUI

struct PhotoPickerDemo: View {
    @State private var isPresented: Bool = false
    @State var pickerResult: [UIImage] = []
    var config: PHPickerConfiguration  {
       var config = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
        config.filter = .images //videos, livePhotos...
        config.selectionLimit = 0 //0 => any, set 1-2-3 for har limit
        return config
    }
    
    var body: some View {
        ScrollView {
            LazyVStack {
                Button("Present Picker") {
                    isPresented.toggle()
                }.sheet(isPresented: $isPresented) {
                    PhotoPicker(configuration: self.config,
                                pickerResult: $pickerResult,
                                isPresented: $isPresented)
                }
                ForEach(pickerResult, id: \.self) { image in
                    Image.init(uiImage: image)
                        .resizable()
                        .frame(width: UIScreen.main.bounds.width, height: 250, alignment: .center)
                        .aspectRatio(contentMode: .fit)
                }
            }
        }
    }
}

struct PhotoPicker: UIViewControllerRepresentable {
    let configuration: PHPickerConfiguration
    @Binding var pickerResult: [UIImage]
    @Binding var isPresented: Bool
    func makeUIViewController(context: Context) -> PHPickerViewController {
        let controller = PHPickerViewController(configuration: configuration)
        controller.delegate = context.coordinator
        return controller
    }
    func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) { }
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    /// PHPickerViewControllerDelegate => Coordinator
    class Coordinator: PHPickerViewControllerDelegate {
        
        private let parent: PhotoPicker
        
        init(_ parent: PhotoPicker) {
            self.parent = parent
        }
        
        func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
            
            for image in results {
                if image.itemProvider.canLoadObject(ofClass: UIImage.self)  {
                    image.itemProvider.loadObject(ofClass: UIImage.self) { (newImage, error) in
                        if let error = error {
                            print(error.localizedDescription)
                        } else {
                            self.parent.pickerResult.append(newImage as! UIImage)
                        }
                    }
                } else {
                    print("Loaded Assest is not a Image")
                }
            }
            // dissmiss the picker
            parent.isPresented = false
        }
    }
}

struct photoPickerDemo_Previews: PreviewProvider {
    static var previews: some View {
        PhotoPickerDemo()
    }
}

or if you want to crop via user interface like attach picture

enter image description here

Step 1 Using Xcode 12, go to File -> Swift Packages -> Add Package Dependency and enter https://github.com/marshallino16/ImageCropper

Step 2

in your didFinishPicking method where you are receiving selected image pass it in this package using these lines

let ratio = CropperRatio(width: 1, height: 1)//square ratio for crop

ImageCropperView(image: Image(yourSelectedImageHere),cropRect: nil,ratio: ratio).onCropChanged { (newCrop) in
  print(newCrop)//here you will receive cropped image 
}

edited use of ImageCropperView

struct PhotoPicker: UIViewControllerRepresentable {
    let configuration: PHPickerConfiguration
    @Binding var pickerResult: [UIImage]
    @Binding var isPresented: Bool
    func makeUIViewController(context: Context) -> PHPickerViewController {
        let controller = PHPickerViewController(configuration: configuration)
        controller.delegate = context.coordinator
        return controller
    }
    func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) { }
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    /// PHPickerViewControllerDelegate => Coordinator
    class Coordinator: PHPickerViewControllerDelegate {
        
        private let parent: PhotoPicker
        
        init(_ parent: PhotoPicker) {
            self.parent = parent
        }
        
        func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
            
            for image in results {
                if image.itemProvider.canLoadObject(ofClass: UIImage.self)  {
                    image.itemProvider.loadObject(ofClass: UIImage.self) { (newImage, error) in
                        if let error = error {
                            print(error.localizedDescription)
                        } else {
                            let ratio = CropperRatio(width: 1, height: 1)//square ratio for crop
    
                            ImageCropperView(image: Image(newImage),cropRect: nil,ratio: ratio).onCropChanged { (newCrop) in
                               print(newCrop)//here you will receive cropped image 
                          }
                        }
                    }
                } else {
                    print("Loaded Assest is not a Image")
                }
            }
            // dissmiss the picker
            parent.isPresented = false
        }
    }
}