5

I have written this code to capture an image using the AVFoundation library in Swift:

@IBAction func cameraButtonWasPressed(sender: AnyObject) {

    if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo){
        stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection){
            (imageSampleBuffer : CMSampleBuffer!, _) in

            let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)

            var pickedImage: UIImage = UIImage(data: imageDataJpeg)!

            let library = ALAssetsLibrary()
            library.writeImageToSavedPhotosAlbum(pickedImage.CGImage,
                metadata:nil,
                completionBlock:nil)

        }


    }

}

It works fine, but when I go to the photo library the image shows rotated 90 degrees counter clockwise.

Can someone give me an hint on where to dig to fix this?

Rui Gomes
  • 332
  • 1
  • 3
  • 16
  • Hint: http://stackoverflow.com/questions/6976213/why-does-capturing-images-with-avfoundation-give-me-480x640-images-when-the-pres – Robert Gummesson Jan 29 '15 at 22:42
  • Setting the video connection orientation and creating a new UIImage doesn't seem to work. Not sure if I'm doing something wrong. – Rui Gomes Jan 30 '15 at 00:03

3 Answers3

7

Maybe this Swift code can help you.

//correctlyOrientedImage.swift

import UIKit

extension UIImage {

    public func correctlyOrientedImage() -> UIImage {
        if self.imageOrientation == UIImageOrientation.Up {
            return self
        }

        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        self.drawInRect(CGRectMake(0, 0, self.size.width, self.size.height))
        var normalizedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        return normalizedImage;
    }
}

I saw it somewhere in stack overflow and incorporated in my project as well.

Community
  • 1
  • 1
Jay Shin
  • 914
  • 1
  • 7
  • 12
2

You should be using a slightly different writeImage method:

(1) get the orientation from the UIImage imageOrientation property (an enum), and cast it to ALAssetOrientation (an enum with the same Int values as UIImageOrientation)

 var orientation : ALAssetOrientation = ALAssetOrientation(rawValue:           
                                        pickedImage.imageOrientation.rawValue)!

(2) use a similar-but-different method on ALAssetLibrary

library.writeImageToSavedPhotosAlbum(
                pickedImage.CGImage,
                orientation: orientation,
                completionBlock:nil)

This works for me in Objective-C ... I have had a quick go at translating to Swift (as above) but I am getting compiler warnings.

Cannot invoke 'writeImageToSavedPhotosAlbum' with an argument list of type '(CGImage!, orientation: ALAssetOrientation, completionBlock: NilLiteralConvertible)'

Perhaps you could try (I don't have the time to construct a full AVFoundation pipeline in Swift to test this definitively)

If you can't get that to work, the other solution is to extract the exif metadata from the sampleBuffer and pass it through to the method you are already using

library.writeImageToSavedPhotosAlbum(pickedImage.CGImage, metadata:nil, completionBlock:nil

foundry
  • 31,615
  • 9
  • 90
  • 125
  • Thanks @foundry for your good answer! You solved my question http://stackoverflow.com/questions/28843045/save-image-with-the-correct-orientation-swift-core-image/28845429#28845429 Answer there if you want and I will check it as correct. – benLIVE Mar 04 '15 at 13:12
  • @benLIVE - which worked for you - using `orientation` version or extracting the metadata and using the `metadata` version? – foundry Mar 04 '15 at 13:24
  • Using the orientation. I was using the method writeImageToSavedPhotosAlbum with metadata and changed to orientation, just like your example. Would be good to know a way to edit the metadata because there's not only the orientation but the GeoLocation etc. @foundry – benLIVE Mar 04 '15 at 17:23
0

Swift 5

extension UIImage {
    public func correctlyOrientedImage() -> UIImage {
        if self.imageOrientation == UIImage.Orientation.up {
            return self
        }
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()!;
        UIGraphicsEndImageContext();

        return normalizedImage;
    }
}
Azam
  • 797
  • 2
  • 8
  • 23