Another photo orientation question

Hi


I'm using Swift 4 and the AvCam example code from Apple. In my own app I've an issue where the captured image orientation is wrong. My requirement is to save the photos to my applications folder as opposed to the Photos library. I've spent a day trying to correct my own code and got nowhere.


As a test I modified the AvCam code to write the photo data to a static variable in a struct and then display that image on the camera view in AvCam by tapping a button as follows:


// In the camera view controller:


@IBOutlet weak var pv: UIImageView! // for previewing test


@IBAction func btn(_ sender: UIButton) { // for setting preview test image

let dataProvider = CGDataProvider(data: photoTest.photo! as CFData)

let cgImageRef: CGImage! = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent)

let photo = UIImage(cgImage: cgImageRef)

pv.contentMode = .scaleAspectFill

pv.image = photo


}


The orientaion issue is replicated in AvCam with the above code. In my own app the image is previewed before saving to the apps folder and the images orientation is always wrong in the preview as well as when reloading the image from disk. I.e. if the iphone is in portrait orientation, the preview image is rotated 90 degrees anti-clockwise, in landscape the same happens so the preview image appears to be the correct way up.


I'm assuming I've completely missed the point somewhere along the line as it seems to me that regardless of device orientation, the top of a photo should always be the top. For example, in the Photos app photos are shown the correct way up regardless of orientation.


Any help would be much appreciated, this is driving me nuts ;o)


Cheers

Accepted Reply

Simple. AVCapturePhotoOutput returns you an AVCapturePhoto from which you can get the fileDataRepresentation (NSData). Simply write that data to file in your app's sandbox using the appropriate extensions for the still image type you've captured (jpg, heic, dng, tiff, etc).

Replies

Simple. AVCapturePhotoOutput returns you an AVCapturePhoto from which you can get the fileDataRepresentation (NSData). Simply write that data to file in your app's sandbox using the appropriate extensions for the still image type you've captured (jpg, heic, dng, tiff, etc).

Hi bford

Thanks for the reply. That’s pretty much what I’m doing, also saving url and location data to core data.

In the code above, the problem is the preview image is not oriented correctly. Given the AvCam works perfectly, what can be wrong with the preview code?

I’ve abandoned my own code for now, the assumption being I’m a bit of a muppet, and am trying to get a simple preview image view working (see code above) using AvCam as a starter. Saving and retrieving the images is easy enough, just can’t seem to get the display oriented correctly.

Given the code above is simply taking the data that AvCam uses to create the asset, is there something else I need to do to get the orientation sorted.

Many thanks

Looks like it’s time for me to dig out my Kermit the Frog outfit.

For anyone with the same issue, bford was right, but... easily misunderstood (in my case).

I modified the code to save the image first, and then load it into my preview image view and it works.

In my first post I was taking the photo data and converting it to an image without saving it to file. I’ve no idea why it didn’t work, and kind of dislike having to save something to file that may end up getting deleted immediately, but hey that’s nothing compared to banging my head against the wall for 2 days.

bford.... Thanks very much for helping, you saved my sanity!

@HeshanY is correct, use the answer from Yodagama on SO. This only thing is he didn't add how to detect the orientation

if let photoOutputConnection = self.photoOutput.connection(with: .video) {

                            // USE the below function HERE
    photoOutputConnection.videoOrientation = videoOrientation()
}
    
photoOutput.capturePhoto(with: settings, delegate: self)

func to detect device orientation:

func videoOrientation() -> AVCaptureVideoOrientation {
    
    var videoOrientation: AVCaptureVideoOrientation!
    
    let orientation: UIDeviceOrientation = UIDevice.current.orientation
    
    switch orientation {
        
    case .faceUp, .faceDown, .unknown:
        
        // let interfaceOrientation = UIApplication.shared.statusBarOrientation
        
        if let interfaceOrientation = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.windowScene?.interfaceOrientation {
            
            switch interfaceOrientation {
                
            case .portrait, .portraitUpsideDown, .unknown:
                videoOrientation = .portrait
            case .landscapeLeft:
                videoOrientation = .landscapeRight
            case .landscapeRight:
                videoOrientation = .landscapeLeft
            @unknown default:
                videoOrientation = .portrait
            }
        }
        
    case .portrait, .portraitUpsideDown:
        videoOrientation = .portrait
    case .landscapeLeft:
        videoOrientation = .landscapeRight
    case .landscapeRight:
        videoOrientation = .landscapeLeft
    @unknown default:
        videoOrientation = .portrait
    }
    
    return videoOrientation
}