Ios 在纵向模式下拍摄的来自图像选择器(UIImagePickerController)的照片显示为拉伸-Xcode 11/SwiftUI

Ios 在纵向模式下拍摄的来自图像选择器(UIImagePickerController)的照片显示为拉伸-Xcode 11/SwiftUI,ios,image,uiimagepickercontroller,swiftui,xcode11,Ios,Image,Uiimagepickercontroller,Swiftui,Xcode11,我正在使用UIImagePickerController从相机中捕获照片或从照片库中选择,然后显示图像。这适用于横向/水平方向的照片,但纵向/垂直方向的照片显示为水平伸展 我尝试了.scaledToFit()和.aspectRatio(contentMode:.fit),但它仍然显示为拉伸。非常感谢您的帮助 显示图像的代码: struct AddNewItem: View { @State private var showImagePicker: Bool = true @State

我正在使用UIImagePickerController从相机中捕获照片或从照片库中选择,然后显示图像。这适用于横向/水平方向的照片,但纵向/垂直方向的照片显示为水平伸展

我尝试了.scaledToFit()和.aspectRatio(contentMode:.fit),但它仍然显示为拉伸。非常感谢您的帮助

显示图像的代码:

struct AddNewItem: View     {

@State private var showImagePicker: Bool = true
@State private var image: UIImage = nil
@State var showCamera: Bool = false
@State private var showImageEditor: Bool = false


var body: some View {
    VStack {

        Image(uiImage: image ?? UIImage(named: "placeholder")!)
            .resizable()
            .scaledToFit()
            .aspectRatio(contentMode: .fit)

    }
    //Show the photo capture view
    .sheet(isPresented: self.$showImagePicker) {
        PhotoCaptureView(showImagePicker: self.$showImagePicker, image: self.$image, showImageEditor: self.$showImageEditor, showCamera: self.$showCamera)
    }
}
}

图像选择器协调器:

class ImagePickerCoordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

@Binding var isShown: Bool
@Binding var image: UIImage?
@Binding var showEditor: Bool

init(isShown: Binding<Bool>, image: Binding<UIImage?>, showEditor: Binding<Bool>) {
    _isShown = isShown
    _image = image
    _showEditor = showEditor
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
    image = uiImage
    isShown = false
    showEditor = true
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    isShown = false
}

}我也有同样的问题。我在makeUIViewController函数中将editingMode设置为true,从而避免了这种情况:

func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
    let imagePicker = UIImagePickerController()
    imagePicker.allowsEditing = true
    imagePicker.delegate = context.coordinator
    return imagePicker
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        guard let image = info[.editedImage] as? UIImage else {
            print("No image found")
            return
        }
        parent.imageController.originalImage = image
        parent.showImagePicker = false
    }

这样可以防止图像被拉伸。然而,用户只能选择一张裁剪成正方形的照片。我正在做一个变通方法。

我最终通过获取每个图像的尺寸来计算纵横比,然后使用.aspectRatio(self.imageAspectRatio,contentMode:.fit)手动应用纵横比来解决问题


通过在显示之前在图形上下文中重新绘制图像解决了此问题:

func重画(图像:UIImage)->UIImage?{
let renderer=UIGraphicsImageRenderer(大小:image.size)
返回中的renderer.image{(上下文)
image.draw(in:CGRect(原点:.zero,大小:image.size))
}
}
使用包装的UIImagePickerController:

struct ImagePickerController:UIViewControllerRepresentable{
@绑定var映像:UIImage?
func makeCoordinator()->ImagePickerController.Coordinator{
协调员(自我)
}
func makeUIViewController(上下文:UIViewControllerRepresentableContext)->UIImagePickerController{
让imagePicker=UIImagePickerController()
imagePicker.delegate=context.coordinator
imagePicker.sourceType=.camera
返回图像选择器
}
func updateUIViewController(uViewController:UIImagePickerController,上下文:UIViewControllerRepresentableContext){
}
类协调器:NSObject、UIImagePickerControllerDelegate、UINavigationControllerDelegate{
var控制器:ImagePickerController
init(u控制器:ImagePickerController){
self.controller=控制器
}
func imagePickerController(picker:UIImagePickerController,didFinishPickingMediaWithInfo:[UIImagePickerController.InfoKey:Any]){
picker.disclose(动画:true,完成:nil)
guard let image=info[.originalImage]作为?UIImage else{
返回
}
//需要在图形上下文中绘制以修复SwiftUI纵横比问题
让redrawnImage=redraw(image:image)!
controller.image=重绘图像
}
}
}
在SwiftUI视图中显示为图纸:

struct-camerapcker:View{
@状态变量isOpen=false
@状态变量映像:UIImage?
var body:一些观点{
VStack{
如果图像!=nil{
图像(uiImage:Image!)
.可调整大小()
.scaledofit()
.框架(宽度:60,高度:60,对齐:。中心)
}
按钮(操作:{
self.isOpen=true
}){文本(“拍照”)}
}
}.表(显示:$isOpen,onDismiss:{
self.isOpen=false
},内容:{
ImagePickerController(图像:self.$image)
})
}

我发现了一些东西。看起来这里有工作。在didFinishPickingMediaWithInfo中,您应该将所选图像旋转360度

        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            parent.selectedImage = image.rotate(radians: (360.0 * .pi / 180))!
            parent.selectedVideoURL = URL(fileURLWithPath: "")
        }
我从这篇文章中得到了旋转方法:


我希望你能工作。

这就是我正在做的,为UIImage添加了一个可重用的扩展。这是一个非常酷的解决方案,允许用户选择他们的图像的一部分!首先,重绘方法非常慢,并且会阻碍主线程。其次,我的iphone xs在计算过程中重启了好几次。
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        guard let image = info[.editedImage] as? UIImage else {
            print("No image found")
            return
        }
        parent.imageController.originalImage = image
        parent.showImagePicker = false
    }
   func calculateAspectRatio(image: UIImage) -> CGFloat {
    let imageW = image.size.width
    let imageH = image.size.height
    let imageAspectRatio = imageW/imageH
    return imageAspectRatio
} 



Image(uiImage: image ?? UIImage(named: "placeholder")!)
     .aspectRatio(self.imageAspectRatio, contentMode: .fit)
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            parent.selectedImage = image.rotate(radians: (360.0 * .pi / 180))!
            parent.selectedVideoURL = URL(fileURLWithPath: "")
        }