SwiftUI AspectRatio funktioniert nicht für Bilder von der Kamera

8

Ich bin mir nicht sicher, ob dies ein SwiftUI-spezifisches Problem ist. Wie auch immer, ich habe einen UIImagePickerController, den ich mithilfe des UIViewControllerRepresentableProtocol in eine SwiftUI-Ansicht implementiert habe:

struct ContentView: View {

@State var showCameraView = false
@State var showImagePicker = false
@State var UserImage = Image("user")

var body: some View {
    VStack {
        UserImage
            .resizable()
            .frame(width: 200, height: 200)
            .scaledToFit()
            .background(Color.gray)
            .cornerRadius(200)
            .clipped()
        Button(action: {self.showImagePicker = true}) {
            Text("Choose from camera roll")
        }
            .padding(.top, 10)
    }
        .sheet(isPresented: $showImagePicker) {
            ImagePicker(showImagePicker: self.$showImagePicker, pickedImage: self.$UserImage)
            }

}

}}

struct ImagePicker: UIViewControllerRepresentable {

@Binding var showImagePicker: Bool
@Binding var pickedImage: Image

func makeCoordinator() -> ImagePicker.Coordinator {
    Coordinator(self)
}

func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
    let imagePicker = UIImagePickerController()
    imagePicker.delegate = context.coordinator
    return imagePicker
}

func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
    return
}

class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    var parent: ImagePicker

    init(_ imagePicker: ImagePicker) {
        self.parent = imagePicker
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
        parent.pickedImage = Image(uiImage: uiImage)
        parent.showImagePicker = false
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        parent.showImagePicker = false
    }
}

}}

Dies funktioniert einwandfrei, wenn Bilder ausgewählt werden, die nicht von der Kamera des Geräts aufgenommen wurden. Jedes Mal, wenn ich ein Bild auswähle, das von der Kamera selbst aufgenommen wurde, wird der Modifikator .aspectRatio anscheinend nicht angewendet, da in diesem Fall die Abmessungen des geladenen Bilds verzerrt sind. Findet jemand etwas in meinem Code falsch oder kennt er eine Lösung?

Andreas Schultz
quelle

Antworten:

5

Ich hatte das gleiche Problem. Ich habe keine Lösung gefunden, aber eine Problemumgehung. Ich habe die Größe des Bildes mit einer Funktion in der Koordinatorklasse geändert, bevor ich es wieder in die Ansicht zurückbringe. Funktioniert bei mir.

func resizeImage(image: UIImage) -> UIImage {
    let scale = 300 / image.size.width
    let newHeight = image.size.height * scale
    UIGraphicsBeginImageContext(CGSize(width: 300, height: newHeight))
    image.draw(in: CGRect(x: 0, y: 0, width: 300, height: newHeight))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage!
}
Ninjahamster
quelle
1
Diese Antwort funktioniert wirklich gut, danke!
Daniel Barclay
3

Hatte das gleiche Problem. Ich habe eine modifizierte Version der von @ninjahamster vorgeschlagenen verwendet, bei der ich die Größe des Bildes einfach nicht geändert habe. Jede andere Lösung ist willkommen.

    func resizeImage(image: UIImage) -> UIImage {
        let width = image.size.width
        let height = image.size.height
        UIGraphicsBeginImageContext(CGSize(width: width, height: height))
        image.draw(in: CGRect(x: 0, y: 0, width: width, height: height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage!
    }
Vincent Garcia
quelle