In my app, I am importing selected photos from a user's photo library and using them as thumbnails/displaying them in UIImageView
s. They are imported and saved to the user's documents folder.
The code used is below, however the images are being automatically rotated before being saved, and I'm not sure why.
For example, this image is rotated 180°: https://imgur.com/a/r2xm0if, as are some others that are wider than they are high. I'm not sure why, but not all images are rotated like this. Some are rotated 90°, and some not at all.
They are rotated on the disk - not just in the UIImageView
, so I know it's not an issue with how that is set up.
importPicture() is called when the user taps a "+" button.
@objc func importPicture() {
let picker = UIImagePickerController()
picker.mediaTypes = [kUTTypeMovie as String, kUTTypeImage as String]
picker.allowsEditing = true
picker.delegate = self
present(picker, animated: true)
}
@objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let documentsDirectoryURL = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
// create a name for your image
let addedURL = UUID().uuidString
let fileURL = documentsDirectoryURL.appendingPathComponent("\(addedURL).png")
let videoURL2 = documentsDirectoryURL.appendingPathComponent("\(addedURL).mov")
let mediaType = info[UIImagePickerController.InfoKey.mediaType] as AnyObject
// Movie
if mediaType as! String == kUTTypeMovie as String {
let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as? URL
print("VIDEO URL: \(videoURL!)")
let myVideoVarData = try! Data(contentsOf: videoURL! as URL)
if !FileManager.default.fileExists(atPath: videoURL2.path) {
do {
try myVideoVarData.write(to: videoURL2)
print("Video Added Successfully")
print(videoURL2)
} catch {
print(error)
}
} else {
print("Video not added")
}
photosNew.append("\(addedURL).mov")
collectionView.reloadData()
}
// Image
if mediaType as! String == kUTTypeImage as String {
guard let image = info[.originalImage] as? UIImage else {
return
}
if let imageData = image.pngData() {
if !FileManager.default.fileExists(atPath: fileURL.path) {
do {
try imageData.write(to: fileURL)
print("Image Added Successfully")
print(fileURL)
} catch {
print(error)
}
} else {
print("Image Not Added")
}
}
photosNew.append("\(addedURL).png")
collectionView.reloadData()
}
Created an UIImage
extension to keep the image in the original position,
extension UIImage {
func fixedOrientation() -> UIImage {
if imageOrientation == .up {
return self
}
var transform: CGAffineTransform = CGAffineTransform.identity
switch imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: size.width, y: size.height)
transform = transform.rotated(by: CGFloat.pi)
case .left, .leftMirrored:
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.rotated(by: CGFloat.pi / 2)
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: size.height)
transform = transform.rotated(by: CGFloat.pi / -2)
case .up, .upMirrored:
break
}
switch imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: size.height, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .up, .down, .left, .right:
break
}
if let cgImage = self.cgImage, let colorSpace = cgImage.colorSpace,
let ctx: CGContext = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) {
ctx.concatenate(transform)
switch imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
default:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
}
if let ctxImage: CGImage = ctx.makeImage() {
return UIImage(cgImage: ctxImage)
} else {
return self
}
} else {
return self
}
}
}
To use the extension's method, please should do the following with your image
,
let orientedImage = image?.fixedOrientation()
In your case, inside func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
method,
...
guard let image = info[.originalImage] as? UIImage else {
return
}
let orientedImage = image.fixedOrientation()
if let imageData = orientedImage.pngData() {
...