You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS AVFoundation竖屏拍照问题:Xcode10.2 Swift5设置后仍存横屏

解决AVCapturePhotoOutput竖屏设置后照片仍横屏保存的问题

嘿,这个坑我之前踩过!你明明设置了photoOutput.connection(with: .video)?.videoOrientation = .portrait,但照片还是横屏保存,核心原因通常是方向设置的时机不对,或者没有考虑设备物理朝向的动态变化。咱们一步步来搞定:

1. 关键:在拍照前重新设置方向

你目前是在configurePhotoOutput()里一次性设置方向,但这个方法只在初始化时执行一次。如果之后设备旋转了,或者Capture Session的连接状态发生变化,之前的设置就会失效。正确的做法是每次调用拍照方法前,都重新检查并设置方向。

先写一个工具方法,把设备的物理朝向转换成AVCaptureVideoOrientation:

private func currentVideoOrientation() -> AVCaptureVideoOrientation {
    let deviceOrientation = UIDevice.current.orientation
    switch deviceOrientation {
    case .portrait:
        return .portrait
    case .portraitUpsideDown:
        return .portraitUpsideDown
    case .landscapeLeft:
        return .landscapeRight // 注意这里的映射,设备的landscapeLeft对应捕获会话的landscapeRight
    case .landscapeRight:
        return .landscapeLeft
    default:
        // 设备朝向未知时默认竖屏
        return .portrait
    }
}

然后在你的拍照方法里,添加方向设置逻辑:

func capturePhoto() {
    guard let photoOutput = self.photoOutput else { return }
    
    // 拍照前强制设置当前正确的方向
    if let videoConnection = photoOutput.connection(with: .video) {
        if videoConnection.isVideoOrientationSupported {
            videoConnection.videoOrientation = currentVideoOrientation()
        }
    }
    
    let photoSettings = AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecJPEG])
    photoOutput.capturePhoto(with: photoSettings, delegate: self)
}

2. 处理照片输出时的方向元数据

有些情况下,即使设置了connection的方向,照片的原始数据还是会保留设备捕获时的方向信息,需要在代理方法里根据元数据调整图片方向:

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    guard error == nil, let imageData = photo.fileDataRepresentation() else {
        print("照片处理失败:\(error?.localizedDescription ?? "未知错误")")
        return
    }
    
    var capturedImage = UIImage(data: imageData)
    // 从照片元数据中获取方向信息
    if let orientationMetadata = photo.metadata[String(kCGImagePropertyOrientation)] as? UInt32,
       let uiOrientation = UIImage.Orientation(rawValue: orientationMetadata) {
        capturedImage = UIImage(cgImage: capturedImage!.cgImage!, scale: capturedImage!.scale, orientation: uiOrientation)
    }
    
    // 现在capturedImage就是正确方向的图片,可用于保存或展示
    UIImageWriteToSavedPhotosAlbum(capturedImage!, nil, nil, nil)
}

3. 额外检查点

  • 确保你的captureSession的sessionPreset不是强制横屏的(比如AVCaptureSession.Preset.hd1920x1080其实也支持竖屏,但如果自定义了分辨率,要确认宽高比适配竖屏)
  • 确认photoOutput.connection(with: .video)不为nil,有时候如果session配置有问题,连接可能无法获取到

内容的提问来源于stack exchange,提问作者mhmaidi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:07:23