On my iOS app written in Swift I need to take pictures and save them on gallery; as Apple documentation, all the pictures are taken in landscape also if the phone is in portrait; if we save the picture as-is it will be saved 90° rotated.
The question: How can I correctly manage the device orientation when saving picture?
Thank to some searches I used this solution:
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
// ...error handling here
guard let imageData = photo.fileDataRepresentation(with: self) else {
NSLog("Fail to convert pixel buffer")
return
}
// Save image to gallery here
}
My class is AVCapturePhotoFileDataRepresentationCustomizer
delegate, so:
func replacementMetadata(for photo: AVCapturePhoto) -> [String : Any]? {
var properties = photo.metadata
// Image orientation
properties[kCGImagePropertyOrientation as String] = CGImagePropertyOrientation.right
let exifData = NSMutableDictionary(dictionary: properties[kCGImagePropertyExifDictionary as String] as! NSDictionary)
let xDimension = exifData[kCGImagePropertyExifPixelYDimension as String]
let yDimension = exifData[kCGImagePropertyExifPixelXDimension as String]
if xDimension != nil && yDimension != nil {
exifData[kCGImagePropertyExifPixelXDimension as String] = xDimension
exifData[kCGImagePropertyExifPixelYDimension as String] = yDimension
properties[kCGImagePropertyExifDictionary as String] = exifData
}
return properties
}
Because the image is shot in portrait the orientation is .right
and I read in my searches that also the X and Y dimensions in exif data should be swapped.
Unfortunately everything lead no result: Inspecting the saved image with an exif explorer image orientation is still a 0=unknown value and X and Y as originally set.
I’m sure the data is correctly set and written because:
-
Breakpoing on
return properties
underlined that the orientation tag set correctly; moreover if a tag is not correctly set or unknown the app crashes… -
In the same
replacementMetadata
function I also set GPS data (I cut this for simplicity here!) and I wrote some test value (like heading = 101) and these data are correctly reported on the final image metadata.
So my question remains … Thank you for pointing me in the right direction with code snippets or documents.
2
Answers
You may set your shot orientation to whatever you like by setting
videoOrientation
of yourAVCapturePhotoOutput
.To match it with the current device orientation, you may use
UIDevice.current.orientation
manually converted toAVCaptureVideoOrientation
.Conversion from
UIDeviceOrientation
toAVCaptureVideoOrientation
:In your file having camera code:
Start measuring orientation when camera is active.
Stop measuring orientation when camera is not in use.
Finally add one line just before calling capturePhoto(with: settings, delegate: self)