SwiftUI AspectRatioがカメラからの画像に対して機能しない


8

これがSwiftUI固有の問題かどうかはわかりません。とにかく、UIViewControllerRepresentableProtocolを使用してSwiftUIビューに実装したUIImagePickerControllerがあります。

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
    }
}

}

デバイスのカメラで撮影されていない画像を選択すると、正常に機能します。ただし、カメラ自体が取得した画像を選択するたびに、この場合、読み込まれた画像の寸法が歪むため、.aspectRatio修飾子が適用されないようです。誰かが私のコードで何か問題を見つけたり、解決策を知っていますか?

回答:


6

同じ問題が発生しました。解決策は見つかりませんでしたが、回避策はありました。コーディネータークラスの関数を使用して画像のサイズを変更し、ビューに戻します。私のために働く。

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!
}

1
この答えは本当にうまくいきます、ありがとう!
Daniel Barclay

3

同じ問題があった。私は、@ ninjahamsterによって提案されたものの修正バージョンを使用しましたが、イメージのサイズを変更していません。他のソリューションは大歓迎です。

    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!
    }

2

同じ問題に遭遇しました。SwiftUIに欠けていることに気づかなかった!! 今、私は忍者ハムスターの回避策を適用しました。

誰かが何らかの参照を必要とする場合に備えて、ここに私のコード。funcの変更を参照してくださいdidFinishPickingMediaWithInfo

import SwiftUI

final class ImagePickerCoordinator: NSObject {
    @Binding var image: UIImage?
    @Binding var takePhoto: Bool

    init(image: Binding<UIImage?>, takePhoto: Binding<Bool>) {
        _image = image
        _takePhoto = takePhoto
    }
}

struct ImagePicker: UIViewControllerRepresentable {
    @Binding var image: UIImage?
    @Binding var takePhoto: Bool

    func makeCoordinator() -> ImagePickerCoordinator {
        ImagePickerCoordinator(image: $image, takePhoto: $takePhoto)
    }

    func makeUIViewController(context: Context) -> UIImagePickerController {
        let pickerController = UIImagePickerController()
        pickerController.delegate = context.coordinator
        return pickerController
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {
        switch self.takePhoto {
        case true:
            uiViewController.sourceType = .camera
            uiViewController.showsCameraControls = true
        case false:
            uiViewController.sourceType = .photoLibrary
        }
        uiViewController.allowsEditing = false
    }
}

extension ImagePickerCoordinator: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let imageOriginal = info[.originalImage] as? UIImage {
//            image = imageOriginal
            image = resizeImage(image: imageOriginal)
        }
        if let imageEdited = info[.editedImage] as? UIImage {
            image = imageEdited
        }

        picker.dismiss(animated: true, completion: nil)
    }

    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!
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
}

これありがとう!非常に感謝
MattBlack
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.