2017-10-23 4 views
0

Ich habe eine benutzerdefinierte Kamera, die Foto im Hochformat aufnimmt.Swift - AVFoundation Capture Bildausrichtung

Mein Problem ist, dass, wenn ich versuche, ein Foto im Querformat aufzunehmen und zu speichern, das Bild immer noch im Hochformat gespeichert wird.

Ich habe diese Funktion zur Einrichtung der previewLayer:

static func setupPreviewLayer(view: UIView) { 
    cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 
    cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill 
    switch UIDevice.current.orientation { 
    case .portrait: 
     cameraPreviewLayer?.connection?.videoOrientation = 
     AVCaptureVideoOrientation.portrait 
    case .portraitUpsideDown: 
     cameraPreviewLayer?.connection?.videoOrientation = 
      AVCaptureVideoOrientation.portraitUpsideDown 
    case .landscapeLeft: 
     cameraPreviewLayer?.connection?.videoOrientation = 
     AVCaptureVideoOrientation.landscapeLeft 
    case .landscapeRight: 
     cameraPreviewLayer?.connection?.videoOrientation = 
     AVCaptureVideoOrientation.landscapeRight 
    default: 
     cameraPreviewLayer?.connection?.videoOrientation = 
     AVCaptureVideoOrientation.portrait 
    } 
    cameraPreviewLayer?.frame = view.frame 
    view.layer.insertSublayer(cameraPreviewLayer!, at: 0) 
} 

und ich nenne dies in viewWillAppear (was ich glaube nicht der richtige Weg zu tun ist).

ich als das Foto nehmen:

@IBAction func takePhotoBtnPressed(_ sender: Any) { 
    let settings = AVCapturePhotoSettings() 
    useFlash(settings: settings) 
    settings.isAutoStillImageStabilizationEnabled = true 
    CustomCamera.photoOutput?.capturePhoto(with: settings, delegate: self) 
} 

und verwenden diese Erweiterung:

extension FishCameraVC: AVCapturePhotoCaptureDelegate { 
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { 
    if let imageData = photo.fileDataRepresentation() { 
     image = UIImage(data: imageData) 
     performSegue(withIdentifier: "ShowTakenPhoto", sender: nil) 
    } 
} 

}

Alles funktioniert gut, solange ich ein Portrait-Modus Foto geschossen, aber wenn ich drehen das Telefon, um ein Landschaftsfoto zu schießen, dann wird das Foto noch im Porträt geschossen.

Es ist das erste Mal, dass ich mit einer benutzerdefinierten Kamera arbeite und ich weiß wirklich nicht, wo ich anfangen soll, dies zu beheben ... Wenn jemand helfen könnte würde ich es wirklich zu schätzen wissen.

Vielen Dank!

--------------- UPDATE Ich habe diese Funktion hinzugefügt:

func managePhotoOrientation() -> UIImageOrientation { 
    var currentDevice: UIDevice 
    currentDevice = .current 
    UIDevice.current.beginGeneratingDeviceOrientationNotifications() 
    var deviceOrientation: UIDeviceOrientation 
    deviceOrientation = currentDevice.orientation 

    var imageOrientation: UIImageOrientation! 

    if deviceOrientation == .portrait { 
     imageOrientation = .up 
     print("Device: Portrait") 
    }else if (deviceOrientation == .landscapeLeft){ 
     imageOrientation = .left 
     print("Device: LandscapeLeft") 
    }else if (deviceOrientation == .landscapeRight){ 
     imageOrientation = .right 
     CustomCamera.cameraPreviewLayer?.connection?.videoOrientation = .landscapeRight 
     print("Device LandscapeRight") 
    }else if (deviceOrientation == .portraitUpsideDown){ 
     imageOrientation = .down 
     print("Device PortraitUpsideDown") 
    }else{ 
     imageOrientation = .up 
    } 
    return imageOrientation 
} 

Und änderte meine Erweiterung dazu:

extension FishCameraVC: AVCapturePhotoCaptureDelegate { 
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { 
    if let imageData = photo.fileDataRepresentation() { 
     image = UIImage(data: imageData) 
     let dataProvider = CGDataProvider(data: imageData as CFData) 
     let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent) 
     self.image = UIImage(cgImage: cgImageRef!, scale: 1.0, orientation: imageOrientation!) 
     performSegue(withIdentifier: "ShowTakenPhoto", sender: nil) 
    } 
} 

} Das Bild wird in der Vorschau in der richtigen Ausrichtung angezeigt, aber wenn ich es speichere geht es in Hochformat ...

Antwort

1

Sie müssen den folgenden Code vor dem Aufruf capturePhoto()

if let photoOutputConnection = CustomCamera.photoOutput.connection(with: AVMediaType.video) { 
    photoOutputConnection.videoOrientation = videoDeviceOrientation 
} 

Sie Ihre managePhotoOrientation nutzen könnten, um run() Funktion videoDeviceOrientation zu erhalten.

+0

Danke für die Antwort .... Ich habe meinen Code vollständig geändert, indem ich apple rate als Beispiel genommen habe ... https://developer.apple.com/library/content/samplecode/AVCam/Listings/Swift_AVCam_CameraViewController_swift.html#//apple_ref/doc/uid/DTS40010112-Swift_AVCam_CameraViewController_swift-DontLinkElementID_15 – Marco

+0

jetzt funktioniert es perfekt ... – Marco

+0

AVCam ist, was ich meine Fotoaufnahme auf basiert. Sie sollten das videoOrientation Setup in diesem Code sehen – Spads

0

Ich hatte ein ähnliches Problem und reparierte es, indem ich ein neues Bild basierend auf dem t generierte aken Foto:

UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale) 
image.draw(in: CGRect(origin: .zero, size: image.size)) 
let newImage = UIGraphicsGetImageFromCurrentImageContext() 
UIGraphicsEndImageContext() 

Anscheinend ist die Bild-Metadaten von iOS erzeugt (die die Orientierung enthält) sind unvollständig und einig Zuschauer (in meinem Fall Chrome und Safari-Browser) nicht das Bild richtig zu machen. Durch das erneute Rendern werden die Metadaten für alle Betrachter korrekt festgelegt.

Beachten Sie, dass 1) in meiner App auch das Bild herunterskaliert (ich glaube nicht, dass dies den Effekt ändert) und 2) ich das Bild auf andere Weise erfassen (d. H. UIImagePickerController); trotzdem könntest du meinen hacky fix versuchen.

+0

Danke für die Antwort. Das Problem ist, dass, selbst wenn ich ein neues Bild zeichne, es immer noch im Hochformat bleibt ... Problem scheint zu sein, dass es keinen neuen Previewlayer hinzufügt, wenn ich das Telefon rotiere ... – Marco

+0

Um zu klären: so ist das Bild _taken in die app_ und _displayed in der App_ und hat immer noch die falsche Orientierung? –

+0

Nein ....in der app hat es die richtige ausrichtung, aber wenn ich es speichere, geht es ins porträt ... ich habe ein wenig meinen code geändert ... ich werde meine antwort aktualisieren – Marco

Verwandte Themen