Save image with the correct orientation - Swift & Core Image
Instead of using the metadata
version of writeImageToSavedPhotosAlbum
, you can use :
library.writeImageToSavedPhotosAlbum(
cgimg,
orientation: orientation,
completionBlock:nil)
then you can pass in the orientation directly.
To satisfy Swift, you may need to typecast it first:
var orientation : ALAssetOrientation = ALAssetOrientation(rawValue:
gotImage.imageOrientation.rawValue)!
As per my somewhat inconclusive answer here.
(As you have confirmed, this solution does indeed work in Swift - I derived it, untested, from working Objective-C code)
If you are interested in manipulating other information from image metadata, here are a few related answers I provided to other questions...
Updating UIImage orientation metaData?
Force UIImagePickerController to take photo in portrait orientation/dimensions iOS
How to get author of image in cocoa
Getting a URL from (to) a "picked" image, iOS
And a small test project on github that digs out image metadata from various sources (it's objective-C, but the principles are the same).
Swift PNG Image being saved with incorrect orientation
If you need to save your PNG with correct rotation you will need to redraw your image if its orientation it is not .up
. You can redraw it as follow:
extension UIImage {
func png(isOpaque: Bool = true) -> Data? { flattened(isOpaque: isOpaque)?.pngData() }
func flattened(isOpaque: Bool = true) -> UIImage? {
if imageOrientation == .up { return self }
UIGraphicsBeginImageContextWithOptions(size, isOpaque, scale)
defer { UIGraphicsEndImageContext() }
draw(in: CGRect(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
}
edit/update:
For iOS10+ tvOS10+ you can use UIGraphicsImageRenderer
:
extension UIImage {
func png(isOpaque: Bool = true) -> Data? { flattened(isOpaque: isOpaque).pngData() }
func flattened(isOpaque: Bool = true) -> UIImage {
if imageOrientation == .up { return self }
let format = imageRendererFormat
format.opaque = isOpaque
return UIGraphicsImageRenderer(size: size, format: format).image { _ in draw(at: .zero) }
}
}
Playground testing:
Usage for images without transparency:
let image = UIImage(data: try! Data(contentsOf: URL(string: "https://i.stack.imgur.com/varL9.jpg")!))!
if let data = image.png() {
let imageFromPNGData = UIImage(data: data)
}
With transparency :
if let data = image.png(isOpaque: false) {
let imageFromPNGData = UIImage(data: data)
}
Correctly set the right picture orientation when shooting photo
You may set your shot orientation to whatever you like by setting videoOrientation
of your AVCapturePhotoOutput
.
To match it with the current device orientation, you may use UIDevice.current.orientation
manually converted to AVCaptureVideoOrientation
.
let photoOutput = AVCapturePhotoOutput()
func takeShot() {
// set whatever orientation you like
let myShotOrientation = UIDevice.current.orientation.asCaptureVideoOrientation
if let photoOutputConnection = self.photoOutput.connection(with: .video) {
photoOutputConnection.videoOrientation = myShotOrientation
}
photoOutput.capturePhoto(...)
}
Conversion from UIDeviceOrientation
to AVCaptureVideoOrientation
:
extension UIDeviceOrientation {
///
var asCaptureVideoOrientation: AVCaptureVideoOrientation {
switch self {
// YES, that's not a mistake
case .landscapeLeft: return .landscapeRight
case .landscapeRight: return .landscapeLeft
case .portraitUpsideDown: return .portraitUpsideDown
default: return .portrait
}
}
}
Save UIImage, Load it in Wrong Orientation
I have faced similar problem and here is how I solved it.
While we save image we need to save its orientation information along with the image ...
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setInteger:[myImage imageOrientation] forKey:@"kImageOrientation"];
[imageOrientation release];
And we load image we need to read its orientation information and apply it to the image…
UIImage *tempImage = [[UIImage alloc] initWithContentsOfFile:fullPath];
UIImage *orientedImage= [[UIImage alloc] initWithCGImage: tempImage.CGImage scale:1.0 orientation:imageOrientation];
[tempImage release];
orientedImage
is what we need.
Thanks,
How to save Image in Core Data
Convert UIImage
to NSData
and save.
To save: let data = UIImagePNGRepresentation(image)
To load: let image = UIImage(data: data)
save a rotated picture (swift3)
Change below line
UIImage(cgImage: (otherImage?.cgImage!)!, scale: CGFloat(1.0), orientation: .right)
to
UIImage(cgImage: (otherImage?.cgImage!)!, scale: CGFloat(1.0), orientation: .up)
Related Topics
Determine If Mkmapview Was Dragged/Moved in Swift 2.0
iOS + Swift, How to Redirect to Itunes Purchase Page
How to Rotate an Uiimageview Using Touchesmoved
How to Update a Swiftui View That Was Embedded into Uikit
How to Detect If a Nsattributedstring Contains a Nstextattachment and Remove It
Diffabledatasource: Snapshot Doesn't Reload Headers & Footers
Segue Out of Navigation Controller
-[Uithreadsafenode Canperformaction:Withsender:]: Unrecognized Selector Sent to Instance
How to Create a Rounded Rectangle Label in Xcode 7 and Swift 2
Transforming a Cashapelayer to a Specific Size in Swift
How to Access Index of Tabbar Item Using Swift
How to Use Realm.Addnotificationblock
Convert Urlrequest to Nsmutableurlrequest
How to Add a Ibaction to a Button Programmatically in Swift 4