UIImageOrientation 与相机
Posted
技术标签:
【中文标题】UIImageOrientation 与相机【英文标题】:UIImageOrientation with camera 【发布时间】:2017-02-01 06:46:18 【问题描述】:这是我相机的代码,把前置摄像头换成后置摄像头,如果我用后置摄像头拍照,照片的方向是好的(原始),但如果我用前置摄像头拍照相机获取方向错误的图像。
class TakeSelfieViewController: UIViewController, AVCapturePhotoCaptureDelegate
var captureSession = AVCaptureSession()
var photoOutput = AVCapturePhotoOutput()
var previewLayer : AVCaptureVideoPreviewLayer?
var captureDevice : AVCaptureDevice?
var sessionOutputSetting = AVCapturePhotoSettings(format: [AVVideoCodecKey:AVVideoCodecJPEG])
var toggle = false
@IBOutlet weak var cameraView: UIView!
@IBOutlet weak var tempImageView: UIImageView!
@IBOutlet weak var adorButton: UIButton!
override func viewDidAppear(_ animated: Bool)
super.viewDidAppear(animated)
previewLayer?.frame = cameraView.bounds
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = adorButton.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
adorButton.addSubview(blurEffectView)
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
pickCamera(which: toggle)
func pickCamera(which: Bool)
if (which == true)
let deviceDescovery = AVCaptureDeviceDiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInDualCamera, AVCaptureDeviceType.builtInTelephotoCamera,AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.back)
print("back camera")
startCamera(deviceDesc: deviceDescovery!)
toggle = true
else if (which == false)
let deviceDescovery = AVCaptureDeviceDiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInDualCamera, AVCaptureDeviceType.builtInTelephotoCamera,AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front)
print("front camera")
startCamera(deviceDesc: deviceDescovery!)
toggle = false
func startCamera(deviceDesc: AVCaptureDeviceDiscoverySession!)
for device in (deviceDesc.devices)!
if device.position == AVCaptureDevicePosition.back
do
let input = try AVCaptureDeviceInput(device: device)
if captureSession.canAddInput(input)
captureSession.addInput(input)
if captureSession.canAddOutput(photoOutput)
captureSession.addOutput(photoOutput)
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait
cameraView.layer.addSublayer(previewLayer!)
captureSession.startRunning()
print("ADD Back")
else print("Cannot add input - back")
catch
print("Error")
else if (device.position == AVCaptureDevicePosition.front)
do
let input = try AVCaptureDeviceInput(device: device)
print(input)
if captureSession.canAddInput(input)
captureSession.addInput(input)
if captureSession.canAddOutput(photoOutput)
captureSession.addOutput(photoOutput)
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait
cameraView.layer.addSublayer(previewLayer!)
captureSession.startRunning()
print("ADD Front")
else print("Cannot add input - front")
catch
print(error)
func didPressTakePhoto()
if let videoConnection = photoOutput.connection(withMediaType: AVMediaTypeVideo)
videoConnection.videoOrientation = AVCaptureVideoOrientation.portrait
let settings = AVCapturePhotoSettings(format: [AVVideoCodecKey : AVVideoCodecJPEG])
photoOutput.capturePhoto(with: settings, delegate: self)
func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?)
let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer!, previewPhotoSampleBuffer: previewPhotoSampleBuffer)
let dataProvider = CGDataProvider(data: imageData as! CFData)
let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)
let image = UIImage(cgImage: cgImageRef!, scale: 1.0, orientation: UIImageOrientation.right)
self.tempImageView.image = image
self.tempImageView.isHidden = false
self.yellowButton.isHidden = true
self.toggleAction.isHidden = true
self.adorButton.isHidden = true
print("Hola")
var didTakePhoto = Bool()
@IBOutlet weak var yellowButton: UIButton!
@IBOutlet weak var toggleAction: UIButton!
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
if didTakePhoto
tempImageView.isHidden = true
yellowButton.isHidden = false
toggleAction.isHidden = false
adorButton.isHidden = false
didTakePhoto = false
print("????")
@IBAction func yellowPressed(_ sender: UIButton)
captureSession.startRunning()
didTakePhoto = true
didPressTakePhoto()
print("????")
@IBAction func toggleCamera(_ sender: Any)
if (toggle == false)
print("Changing to back camera")
let currentCameraInput: AVCaptureInput = captureSession.inputs[0] as! AVCaptureInput
captureSession.removeInput(currentCameraInput)
toggle = true
pickCamera(which: toggle)
else if (toggle == true)
print("Changing to front camera")
let currentCameraInput: AVCaptureInput = captureSession.inputs[0] as! AVCaptureInput
captureSession.removeInput(currentCameraInput)
toggle = false
pickCamera(which: toggle)
override var prefersStatusBarHidden: Bool
return true
我该如何解决这个问题? ????
【问题讨论】:
【参考方案1】:使用前置摄像头拍摄的图像是镜像的,当您拍照时,图像方向是在它的 EXIF 字典中获取的,或者在元数据字典中传递。
大多数情况下,当您将其作为 JPG 或 PNG 传递时,如果您不直接处理它,则不会考虑此值。 如果您在风景中拍照,您应该会遇到类似的问题。
在您的捕获方法中,您似乎在应该处理时将方向强制为固定值。
【讨论】:
您的帖子无法访问以上是关于UIImageOrientation 与相机的主要内容,如果未能解决你的问题,请参考以下文章