【问题标题】:SwiftUI AspectRatio does not work for images from cameraSwiftUI AspectRatio 不适用于来自相机的图像
【发布时间】:2020-02-09 20:28:30
【问题描述】:

我不确定这是否是 SwiftUI 特有的问题。无论如何,我有一个 UIImagePickerController,我使用 UIViewControllerRepresentableProtocol 将它实现到 SwiftUI 视图中:

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 修饰符,因为在这种情况下加载的图像的尺寸会失真。有人发现我的代码有问题或知道解决方案吗?

【问题讨论】:

    标签: swift xcode uikit uiimagepickercontroller swiftui


    【解决方案1】:

    我遇到了同样的问题。我没有意识到这是 SwiftUI 的不足!现在我已经应用了 ninjahamster 的解决方法。

    我的代码在这里,以防有人需要参考。查看 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)
        }
    }
    

    【讨论】:

    • 谢谢你!非常感谢
    【解决方案2】:

    有同样的问题。我使用了@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!
        }
    

    【讨论】:

      【解决方案3】:

      我也遇到了同样的问题。我没有找到解决方案,而是一种解决方法。 我使用协调器类中的函数调整了图像的大小,然后将其返回到视图中。对我有用。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-14
        • 1970-01-01
        • 1970-01-01
        • 2018-10-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多