iOS UIImage uploaded to server are rotated [duplicate] - ios

This question already has answers here:
iOS UIImagePickerController result image orientation after upload
(20 answers)
Closed 9 years ago.
I'm using the following code to send an image to a web server. It works, the problem is that the images are rotated for some reason when they get uploaded.
here's my upload method:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self dismissViewControllerAnimated:YES completion:nil];
NSData *image = UIImageJPEGRepresentation([info objectForKey:UIImagePickerControllerOriginalImage], 0.1);
// use token with url for json data from contents of url
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"token"];
NSString *urlString = [NSString stringWithFormat:#"%#%#/photos?token=%#", kIDURLPhoto, listingId, savedValue];
NSLog(#"urlstring for comment is %#",urlString);
self.flUploadEngine = [[fileUploadEngine alloc] initWithHostName:urlString customHeaderFields:nil];
NSMutableDictionary *postParams = [NSMutableDictionary dictionaryWithObjectsAndKeys: #"image", #"caption", nil];
self.flOperation = [self.flUploadEngine postDataToServer:postParams path:nil];
[self.flOperation addData:image forKey:#"picture" mimeType:#"image/jpeg" fileName:#"upload.jpg"];
[self.flOperation addCompletionHandler:^(MKNetworkOperation* operation) {
NSLog(#"%#", [operation responseString]);
// handle a successful 200 response
[self.flUploadEngine enqueueOperation:self.flOperation];
// for iOS7
if ([self respondsToSelector:#selector(setNeedsStatusBarAppearanceUpdate)]) {
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
[self forceReload];
}

Swift 5 Extension:
extension UIImage {
/// Fix image orientaton to protrait up
func fixedOrientation() -> UIImage? {
guard imageOrientation != UIImage.Orientation.up else {
// This is default orientation, don't need to do anything
return self.copy() as? UIImage
}
guard let cgImage = self.cgImage else {
// CGImage is not available
return nil
}
guard let colorSpace = cgImage.colorSpace, let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else {
return nil // Not able to create CGContext
}
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.0)
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: size.height)
transform = transform.rotated(by: CGFloat.pi / -2.0)
case .up, .upMirrored:
break
#unknown default:
fatalError("Missing...")
break
}
// Flip image one more time if needed to, this is to prevent flipped image
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
#unknown default:
fatalError("Missing...")
break
}
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))
break
}
guard let newCGImage = ctx.makeImage() else { return nil }
return UIImage.init(cgImage: newCGImage, scale: 1, orientation: .up)
}
}
Objective C Code :
-(UIImage *)scaleAndRotateImage:(UIImage *)image{
// No-op if the orientation is already correct
if (image.imageOrientation == UIImageOrientationUp) return image;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (image.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, image.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}
switch (image.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, image.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationUp:
case UIImageOrientationDown:
case UIImageOrientationLeft:
case UIImageOrientationRight:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, image.size.width, image.size.height,
CGImageGetBitsPerComponent(image.CGImage), 0,
CGImageGetColorSpace(image.CGImage),
CGImageGetBitmapInfo(image.CGImage));
CGContextConcatCTM(ctx, transform);
switch (image.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,image.size.height,image.size.width), image.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,image.size.width,image.size.height), image.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
Use of code
UIImage *img=[info objectForKey:UIImagePickerControllerOriginalImage];
img=[self scaleAndRotateImage:img];
NSData *image = UIImageJPEGRepresentation(img, 0.1);

Most probably you are not taking into account exif data, they give the rotation of the camera and you should add them to the image EXIF dictionary. In this way when you open the image the reading software can rotate the image accordingly. Check this question and relative answers, it would be helpful

Related

How to load an image and rotate it according to it's orientation exif data and save it with UIImageOrientationUp exif data

How to load an image and rotate it according to it's orientation exif data and save it with UIImageOrientationUp exif data (or without any orientation exif data) so that software that don't handle exif orientation data will show correctly the image ?
Loading an image is as simple as this line:
UIImage *image = [UIImage imageNamed:#"NameOfImageHere"];
Or if you got image data:
NSData *imageData = [[NSData alloc] init];
UIImage *image = [UIImage imageWithData: imageData];
And following method will help you to fix the orientation using exif data within UIImage
- (UIImage *)imageByFixingOrientation {
UIImage *image = self;
if (image.imageOrientation == UIImageOrientationUp) return image;
CGAffineTransform transform = CGAffineTransformIdentity;
switch (image.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, image.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}
switch (image.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, image.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationUp:
case UIImageOrientationDown:
case UIImageOrientationLeft:
case UIImageOrientationRight:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, image.size.width, image.size.height,
CGImageGetBitsPerComponent(image.CGImage), 0,
CGImageGetColorSpace(image.CGImage),
CGImageGetBitmapInfo(image.CGImage));
CGContextConcatCTM(ctx, transform);
switch (image.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
CGContextDrawImage(ctx, CGRectMake(0,0,image.size.height,image.size.width), image.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,image.size.width,image.size.height), image.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
Swift 4 equivalent of my previous objective-c method as an extension:
extension UIImage {
func byFixingOrientation(andResizingImageToNewSize newSize: CGSize? = nil) -> UIImage {
guard let cgImage = self.cgImage else { return self }
let orientation = self.imageOrientation
guard orientation != .up else { return UIImage(cgImage: cgImage, scale: 1, orientation: .up) }
var transform = CGAffineTransform.identity
let size = newSize ?? self.size
if (orientation == .down || orientation == .downMirrored) {
transform = transform.translatedBy(x: size.width, y: size.height)
transform = transform.rotated(by: .pi)
}
else if (orientation == .left || orientation == .leftMirrored) {
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.rotated(by: CGFloat.pi / 2)
}
else if (orientation == .right || orientation == .rightMirrored) {
transform = transform.translatedBy(x: 0, y: size.height)
transform = transform.rotated(by: -(CGFloat.pi / 2))
}
if (orientation == .upMirrored || orientation == .downMirrored) {
transform = transform.translatedBy(x: size.width, y: 0);
transform = transform.scaledBy(x: -1, y: 1)
}
else if (orientation == .leftMirrored || orientation == .rightMirrored) {
transform = transform.translatedBy(x: size.height, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
}
// Now we draw the underlying CGImage into a new context, applying the transform calculated above.
guard let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height),
bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0,
space: cgImage.colorSpace!, bitmapInfo: cgImage.bitmapInfo.rawValue)
else {
return UIImage(cgImage: cgImage, scale: 1, orientation: orientation)
}
ctx.concatenate(transform)
// Create a new UIImage from the drawing context
switch (orientation) {
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))
}
return UIImage(cgImage: ctx.makeImage() ?? cgImage, scale: 1, orientation: .up)
}
}
Usage-1
let newImage = image.byFixingOrientation()
Usage-2 (Fix orientation and resize image to new size)
let newImage = image.byFixingOrientation(andResizingImageToNewSize: CGSize(width: 200, height: 200))

ImageView rotating when using imagePicker

I have a table view and in the cell, there is an image and 2 labels. I am using imagePicker to choose a photo from my camera roll and putting that photo into the cell image. However, when the photo is a portrait mode photo, the image is rotated 90 degrees.
In the code below, posting is an outlet that connects to the imageview in the table view cell and I initialized a UIImagePickerController.
class MakePostVC: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var postImg: UIImageView!
#IBOutlet weak var postTitle: UITextField!
#IBOutlet weak var postDescrip: UITextField!
var imgPicker: UIImagePickerController!
override func viewDidLoad() {
super.viewDidLoad()
postImg.layer.cornerRadius = 30
postImg.clipsToBounds = true
imgPicker = UIImagePickerController()
imgPicker.delegate = self
}
Here is my function for didFinishPickingImage:
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
imgPicker.dismissViewControllerAnimated(true, completion: nil)
postImg.image = image
}
I've looked at similar posts here on SO but the solutions don't seem to work.
Any suggestions?
Thanks
Updated to Swift 5.3, iOS 14
Sunil Sharma's solution worked for me. Here is translated version to Swift 5
extension UIImage {
var fixedOrientation: UIImage {
guard imageOrientation != .up else { return self }
var transform: CGAffineTransform = .identity
switch imageOrientation {
case .down, .downMirrored:
transform = transform
.translatedBy(x: size.width, y: size.height).rotated(by: .pi)
case .left, .leftMirrored:
transform = transform
.translatedBy(x: size.width, y: 0).rotated(by: .pi)
case .right, .rightMirrored:
transform = transform
.translatedBy(x: 0, y: size.height).rotated(by: -.pi/2)
case .upMirrored:
transform = transform
.translatedBy(x: size.width, y: 0).scaledBy(x: -1, y: 1)
default:
break
}
guard
let cgImage = cgImage,
let colorSpace = cgImage.colorSpace,
let context = CGContext(
data: nil, width: Int(size.width), height: Int(size.height),
bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0,
space: colorSpace, bitmapInfo: cgImage.bitmapInfo.rawValue
)
else { return self }
context.concatenate(transform)
var rect: CGRect
switch imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
rect = CGRect(x: 0, y: 0, width: size.height, height: size.width)
default:
rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
}
context.draw(cgImage, in: rect)
return context.makeImage().map { UIImage(cgImage: $0) } ?? self
}
}
UIImage consists a property named imageOrientation.As this property is described in Apple documentation:
Image orientation affects the way the image data is displayed when
drawn. By default, images are displayed in the “up” orientation. If
the image has associated metadata (such as EXIF information), however,
this property contains the orientation indicated by that metadata.
So this property is used to reflect the positioning of the camera with respect to the ground.So when you take an image from phone camera then it saves the orientation flag in UIImage imageOrientation property.
While displaying if this property is ignored then you may not find your image in the right orientation.Just for reference see image below how camera takes image and then encoded and displayed.Check this link for more detail.
To fix this problem in ios
Objective-C
Make category
UIImage+fixOrientation.h
#interface UIImage (fixOrientation)
- (UIImage *)fixOrientation;
#end
UIImage+fixOrientation.m
#implementation UIImage (fixOrientation)
- (UIImage *)fixOrientation {
// No-op if the orientation is already correct
if (self.imageOrientation == UIImageOrientationUp) return self;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (self.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}
switch (self.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationUp:
case UIImageOrientationDown:
case UIImageOrientationLeft:
case UIImageOrientationRight:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform);
switch (self.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
#end
Swift
Make extension as
extension UIImage {
func fixOrientation() -> UIImage {
// No-op if the orientation is already correct
if ( self.imageOrientation == UIImageOrientation.Up ) {
return self;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform: CGAffineTransform = CGAffineTransformIdentity
if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
}
if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
}
if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2));
}
if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
}
if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage).rawValue)!;
CGContextConcatCTM(ctx, transform)
if ( self.imageOrientation == UIImageOrientation.Left ||
self.imageOrientation == UIImageOrientation.LeftMirrored ||
self.imageOrientation == UIImageOrientation.Right ||
self.imageOrientation == UIImageOrientation.RightMirrored ) {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
} else {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
}
// And now we just create a new UIImage from the drawing context and return it
return UIImage(CGImage: CGBitmapContextCreateImage(ctx)!)
}
}
You can rotate image like this post :
https://stackoverflow.com/a/1317194/3928412
also you need to get the device rotation, you can get it like:
UIDevice.currentDevice().orientation

Taking pictures with camera rotates asset.fullScreenImage 90 degrees?

I have a user pick a picture to crop from their Camera Roll. I display all of these pictures as thumbnails for the user to press.
I use UIImage(CGImage: asset.fullScreenImage!.CGImage!, scale: scale, orientation: UIImageOrientation.Up) to ensure that my image remains the same way it faces in the thumbnail. With asset.fullResolutionImage! this doesn't work.
Now comes the weird part. When I take a picture with the iPhone camera, then head to my cropping ViewController, the image is rotated 90 degrees! I have no idea why.
If I leave my app, take a picture with the camera normally, save it to my camera roll, and then choose it from the list of thumbnails like I do other pictures, it works perfectly fine.
What is the cause of this? How does one fix it?
Edit: There are two solutions posted below. One in Objective-C, and the other being a translated copy of that into Swift.
You can try to use this category:
UIImage+FixOrientation.h
UIImage+FixOrientation.m
It is built in Objective-C, then you can use bridging header to use ObjC in combination with Swift, or you can just have a look to understand how to fix that.
Usage example:
UIImage *image = <image from camera image>
image = [image fixOrientation];
This answer is to complement gontovnik's answer.
I have taken his Objective-C solution and written it in Swift. Put this function wherever needed. Just pass in the UIImage in question.
That said, you could probably just make this a UIImage class function. Would actually be nice to just call UIImage.fixOrientation(image: imageInQuestion).
func fixOrientation(image: UIImage) -> UIImage {
// No-op if the orientation is already correct
if (image.imageOrientation == UIImageOrientation.Up) { return image; }
println(image.imageOrientation)
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform = CGAffineTransformIdentity
switch (image.imageOrientation) {
case .Down, .DownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
break
case .Left, .LeftMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
break
case .Right, .RightMirrored:
transform = CGAffineTransformTranslate(transform, 0, image.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
break
case .Up, .UpMirrored:
break
}
switch (image.imageOrientation) {
case .UpMirrored, .DownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
break
case .LeftMirrored, .RightMirrored:
transform = CGAffineTransformTranslate(transform, image.size.height, 0)
transform = CGAffineTransformScale(transform, -1, 1)
break
case .Up, .Down, .Left, .Right:
break
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
var ctx = CGBitmapContextCreate(nil, Int(image.size.width), Int(image.size.height), CGImageGetBitsPerComponent(image.CGImage), 0, CGImageGetColorSpace(image.CGImage), CGImageGetBitmapInfo(image.CGImage))
CGContextConcatCTM(ctx, transform);
switch (image.imageOrientation) {
case .Left, .LeftMirrored, .Right, .RightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.height, image.size.width), image.CGImage)
break
default:
CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage)
break
}
// And now we just create a new UIImage from the drawing context
var cgimg = CGBitmapContextCreateImage(ctx)
var img = UIImage(CGImage: cgimg)
return img!
}
Swift 3 version
func fixOrientation(image: UIImage) -> UIImage {
// No-op if the orientation is already correct
if (image.imageOrientation == UIImageOrientation.up) { return image; }
print(image.imageOrientation)
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform = CGAffineTransform.identity
switch (image.imageOrientation) {
case .down, .downMirrored:
transform = transform.translatedBy(x: image.size.width, y: image.size.height)
transform = transform.rotated(by: CGFloat(M_PI))
break
case .left, .leftMirrored:
transform = transform.translatedBy(x: image.size.width, y: 0)
transform = transform.rotated(by: CGFloat(M_PI_2))
break
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: image.size.height)
transform = transform.rotated(by: CGFloat(-M_PI_2))
break
case .up, .upMirrored:
break
}
switch (image.imageOrientation) {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: image.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
break
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: image.size.height, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
break
case .up, .down, .left, .right:
break
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx = CGContext(data: nil, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: image.cgImage!.bitsPerComponent, bytesPerRow: 0, space: image.cgImage!.colorSpace!, bitmapInfo: image.cgImage!.bitmapInfo.rawValue)
ctx!.concatenate(transform);
switch (image.imageOrientation) {
case .left, .leftMirrored, .right, .rightMirrored:
// Grr...
ctx?.draw(image.cgImage!, in: CGRect(origin: .zero, size: CGSize(width: image.size.height, height: image.size.width)))
break
default:
ctx?.draw(image.cgImage!, in: CGRect(origin: .zero, size: CGSize(width: image.size.width, height: image.size.height)))
break
}
// And now we just create a new UIImage from the drawing context
let cgimg = ctx!.makeImage()
let img = UIImage(cgImage: cgimg!)
return img
}

image orientation in ELCImagepicker [duplicate]

I am testing my iPhone application on an iOS 3.1.3 iPhone. I am selecting/capturing an image using a UIImagePickerController:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setDelegate:self];
[self.navigationController presentModalViewController:imagePicker animated:YES];
[imagePicker release];
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
imageView.image = self.image;
[self.navigationController dismissModalViewControllerAnimated:YES];
submitButton.enabled = YES;
}
I then at some point send it to my web server using the ASI classes:
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:#"http://example.com/myscript.php"]];
[request setDelegate:self];
[request setStringEncoding:NSUTF8StringEncoding];
[request setShouldContinueWhenAppEntersBackground:YES];
//other post keys/values
[request setFile:UIImageJPEGRepresentation(self.image, 100.0f) withFileName:[NSString stringWithFormat:#"%d.jpg", [[NSDate date] timeIntervalSinceNow]] andContentType:#"image/jpg" forKey:#"imageFile"];
[request startAsynchronous];
the problem:
when i take a picture with the iphone while holding it landscape, the image gets uploaded to the server and it viewed like you would expect. when taking a picture holding the phone in portrait, the image is uploaded and viewed as it had been rotated 90 degrees.
my application is set to only work in portrait modes(upsidedown and regular).
How can i make the image always show the correct orientation after uploading?
the image appears to be correct as displayed in an UIImageView(directly after taking the picture), but viewing on the server says otherwise.
A UIImage has a property imageOrientation, which instructs the UIImageView and other UIImage consumers to rotate the raw image data. There's a good chance that this flag is being saved to the exif data in the uploaded jpeg image, but the program you use to view it is not honoring that flag.
To rotate the UIImage to display properly when uploaded, you can use a category like this:
UIImage+fixOrientation.h
#interface UIImage (fixOrientation)
- (UIImage *)fixOrientation;
#end
UIImage+fixOrientation.m
#implementation UIImage (fixOrientation)
- (UIImage *)fixOrientation {
// No-op if the orientation is already correct
if (self.imageOrientation == UIImageOrientationUp) return self;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (self.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}
switch (self.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationUp:
case UIImageOrientationDown:
case UIImageOrientationLeft:
case UIImageOrientationRight:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform);
switch (self.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
#end
I figured out a much simpler one:
- (UIImage *)normalizedImage {
if (self.imageOrientation == UIImageOrientationUp) return self;
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
[self drawInRect:(CGRect){0, 0, self.size}];
UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return normalizedImage;
}
BTW: #Anomie's code does not take scale into account, so will not work for 2x images.
Here is a Swift version of the answer by #an0:
func normalizedImage() -> UIImage {
if (self.imageOrientation == UIImageOrientation.Up) {
return self;
}
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
self.drawInRect(rect)
let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return normalizedImage;
}
Also in a more general function:
func fixOrientation(img:UIImage) -> UIImage {
if (img.imageOrientation == UIImageOrientation.Up) {
return img;
}
UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale);
let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
img.drawInRect(rect)
let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return normalizedImage;
}
Swift 3 version:
func fixOrientation(img: UIImage) -> UIImage {
if (img.imageOrientation == .up) {
return img
}
UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
img.draw(in: rect)
let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return normalizedImage
}
Solution for Swift 3.1 for orientation issue while capturing the image from Camera.
I have updated the solution given by jake and Metal Heart
UIImage extension
//MARK:- Image Orientation fix
extension UIImage {
func fixOrientation() -> UIImage {
// No-op if the orientation is already correct
if ( self.imageOrientation == UIImageOrientation.up ) {
return self;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform: CGAffineTransform = CGAffineTransform.identity
if ( self.imageOrientation == UIImageOrientation.down || self.imageOrientation == UIImageOrientation.downMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: self.size.height)
transform = transform.rotated(by: CGFloat(Double.pi))
}
if ( self.imageOrientation == UIImageOrientation.left || self.imageOrientation == UIImageOrientation.leftMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.rotated(by: CGFloat(Double.pi / 2.0))
}
if ( self.imageOrientation == UIImageOrientation.right || self.imageOrientation == UIImageOrientation.rightMirrored ) {
transform = transform.translatedBy(x: 0, y: self.size.height);
transform = transform.rotated(by: CGFloat(-Double.pi / 2.0));
}
if ( self.imageOrientation == UIImageOrientation.upMirrored || self.imageOrientation == UIImageOrientation.downMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
}
if ( self.imageOrientation == UIImageOrientation.leftMirrored || self.imageOrientation == UIImageOrientation.rightMirrored ) {
transform = transform.translatedBy(x: self.size.height, y: 0);
transform = transform.scaledBy(x: -1, y: 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx: CGContext = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height),
bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0,
space: self.cgImage!.colorSpace!,
bitmapInfo: self.cgImage!.bitmapInfo.rawValue)!;
ctx.concatenate(transform)
if ( self.imageOrientation == UIImageOrientation.left ||
self.imageOrientation == UIImageOrientation.leftMirrored ||
self.imageOrientation == UIImageOrientation.right ||
self.imageOrientation == UIImageOrientation.rightMirrored ) {
ctx.draw(self.cgImage!, in: CGRect(x: 0,y: 0,width: self.size.height,height: self.size.width))
} else {
ctx.draw(self.cgImage!, in: CGRect(x: 0,y: 0,width: self.size.width,height: self.size.height))
}
// And now we just create a new UIImage from the drawing context and return it
return UIImage(cgImage: ctx.makeImage()!)
}
}
Swift 2.0
//MARK:- Image Orientation fix
extension UIImage {
func fixOrientation() -> UIImage {
// No-op if the orientation is already correct
if ( self.imageOrientation == UIImageOrientation.Up ) {
return self;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform: CGAffineTransform = CGAffineTransformIdentity
if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
}
if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
}
if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2));
}
if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
}
if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage).rawValue)!;
CGContextConcatCTM(ctx, transform)
if ( self.imageOrientation == UIImageOrientation.Left ||
self.imageOrientation == UIImageOrientation.LeftMirrored ||
self.imageOrientation == UIImageOrientation.Right ||
self.imageOrientation == UIImageOrientation.RightMirrored ) {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
} else {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
}
// And now we just create a new UIImage from the drawing context and return it
return UIImage(CGImage: CGBitmapContextCreateImage(ctx)!)
}
}
Use of this UIImage Extension in your code:
let fixOrientationImage=chosenImage.fixOrientation()
place this in your delegate methods of image picker like this
Swift 3.1
//MARK: Image Picker Delegates
func imagePickerController(
_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]){
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
profileImg.contentMode = .scaleAspectFill
let fixOrientationImage=chosenImage.fixOrientation()
profileImg.image = fixOrientationImage
dismiss(animated: true, completion: nil)
}
Swift 2.0
//MARK: Image Picker Delegates
func imagePickerController(
picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject])
{
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
profileImg.contentMode = .ScaleAspectFill
**//Fix the image orientation**
let fixOrientationImage=chosenImage.fixOrientation()
profileImg.image = fixOrientationImage
dismissViewControllerAnimated(true, completion: nil)
}
Swift 4.x/5.0 version of #an0 's solution:
extension UIImage {
func upOrientationImage() -> UIImage? {
switch imageOrientation {
case .up:
return self
default:
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(in: CGRect(origin: .zero, size: size))
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return result
}
}
}
in swift ;)
UPDATE SWIFT 3.0 :D
func sFunc_imageFixOrientation(img:UIImage) -> UIImage {
// No-op if the orientation is already correct
if (img.imageOrientation == UIImageOrientation.up) {
return img;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform:CGAffineTransform = CGAffineTransform.identity
if (img.imageOrientation == UIImageOrientation.down
|| img.imageOrientation == UIImageOrientation.downMirrored) {
transform = transform.translatedBy(x: img.size.width, y: img.size.height)
transform = transform.rotated(by: CGFloat(M_PI))
}
if (img.imageOrientation == UIImageOrientation.left
|| img.imageOrientation == UIImageOrientation.leftMirrored) {
transform = transform.translatedBy(x: img.size.width, y: 0)
transform = transform.rotated(by: CGFloat(M_PI_2))
}
if (img.imageOrientation == UIImageOrientation.right
|| img.imageOrientation == UIImageOrientation.rightMirrored) {
transform = transform.translatedBy(x: 0, y: img.size.height);
transform = transform.rotated(by: CGFloat(-M_PI_2));
}
if (img.imageOrientation == UIImageOrientation.upMirrored
|| img.imageOrientation == UIImageOrientation.downMirrored) {
transform = transform.translatedBy(x: img.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
}
if (img.imageOrientation == UIImageOrientation.leftMirrored
|| img.imageOrientation == UIImageOrientation.rightMirrored) {
transform = transform.translatedBy(x: img.size.height, y: 0);
transform = transform.scaledBy(x: -1, y: 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx:CGContext = CGContext(data: nil, width: Int(img.size.width), height: Int(img.size.height),
bitsPerComponent: img.cgImage!.bitsPerComponent, bytesPerRow: 0,
space: img.cgImage!.colorSpace!,
bitmapInfo: img.cgImage!.bitmapInfo.rawValue)!
ctx.concatenate(transform)
if (img.imageOrientation == UIImageOrientation.left
|| img.imageOrientation == UIImageOrientation.leftMirrored
|| img.imageOrientation == UIImageOrientation.right
|| img.imageOrientation == UIImageOrientation.rightMirrored
) {
ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.height,height:img.size.width))
} else {
ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.width,height:img.size.height))
}
// And now we just create a new UIImage from the drawing context
let cgimg:CGImage = ctx.makeImage()!
let imgEnd:UIImage = UIImage(cgImage: cgimg)
return imgEnd
}
I used this page when designing my app that takes pictures and I found that the following method will correct the orientation and use less memory and processor than previous answers:
CGImageRef cgRef = image.CGImage;
image = [[UIImage alloc] initWithCGImage:cgRef scale:1.0 orientation:UIImageOrientationUp];
This basically just rewraps the actual image data with a new orientation. I was using #an0's code but it makes a new image in memory which can be taxing on a 3264x2448 image that you might get from a camera.
If you enable editing, then the edited image (as opposed to the original) will be oriented as expected:
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.allowsEditing = YES;
// set delegate and present controller
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *photo = [info valueForKey:UIImagePickerControllerEditedImage];
// do whatever
}
Enabling editing allows the user to resize and move the image before tapping "Use Photo"
I achieve this by writing below a few lines of code
extension UIImage {
public func correctlyOrientedImage() -> UIImage {
guard imageOrientation != .up else { return self }
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(in: CGRect(origin: .zero, size: size))
let normalizedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return normalizedImage
}
}
This what I have found for fixing orientation issue
UIImage *initialImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSData *data = UIImagePNGRepresentation(self.initialImage);
UIImage *tempImage = [UIImage imageWithData:data];
UIImage *fixedOrientationImage = [UIImage imageWithCGImage:tempImage.CGImage
scale:initialImage.scale
orientation:self.initialImage.imageOrientation];
initialImage = fixedOrientationImage;
EDIT:
UIImage *initialImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSData *data = UIImagePNGRepresentation(self.initialImage);
initialImage = [UIImage imageWithCGImage:[UIImage imageWithData:data].CGImage
scale:initialImage.scale
orientation:self.initialImage.imageOrientation];
Here’s a solution that doesn’t change the colorspace of the original image. If you want to normalize the orientation of a grayscale image, you are out of luck with all solutions based on UIGraphicsBeginImageContextWithOptions because it creates a context in the RGB colorspace. Instead, you have to create a context with the same properties as the original image and draw:
extension UIImage {
static let rotatedOrentations: [UIImage.Orientation] = [.left, .leftMirrored, .right, .rightMirrored]
func normalizedImage() -> UIImage {
if imageOrientation == .up {
return self
}
let image = self.cgImage!
let swapOrientation = UIImage.rotatedOrentations.contains(imageOrientation)
let width = swapOrientation ? image.height : image.width
let height = swapOrientation ? image.width : image.height
let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: image.bitsPerComponent, bytesPerRow: image.bytesPerRow, space: image.colorSpace!, bitmapInfo: image.bitmapInfo.rawValue)!
let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: CGFloat(height));
context.concatenate(flipVertical)
UIGraphicsPushContext(context)
self.draw(at: .zero)
UIGraphicsPopContext()
return UIImage(cgImage: context.makeImage()!)
}
}
Update for Swift 3.1 based on Sourabh Sharma's answer, with code clean up.
extension UIImage {
func fixedOrientation() -> UIImage {
if imageOrientation == .up { return self }
var transform:CGAffineTransform = .identity
switch imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: size.width, y: size.height).rotated(by: .pi)
case .left, .leftMirrored:
transform = transform.translatedBy(x: size.width, y: 0).rotated(by: .pi/2)
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: size.height).rotated(by: -.pi/2)
default: break
}
switch imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: size.width, y: 0).scaledBy(x: -1, y: 1)
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: size.height, y: 0).scaledBy(x: -1, y: 1)
default: break
}
let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height),
bitsPerComponent: cgImage!.bitsPerComponent, bytesPerRow: 0,
space: cgImage!.colorSpace!, bitmapInfo: cgImage!.bitmapInfo.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))
}
return UIImage(cgImage: ctx.makeImage()!)
}
}
Picker delegate method example:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let originalImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
let fixedImage = originalImage.fixedOrientation()
// do your work
}
Here's UIImage extension for swift:
extension UIImage {
func fixOrientation() -> UIImage {
// No-op if the orientation is already correct
if ( self.imageOrientation == UIImageOrientation.Up ) {
return self;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform: CGAffineTransform = CGAffineTransformIdentity
if ( self.imageOrientation == UIImageOrientation.Down || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
}
if ( self.imageOrientation == UIImageOrientation.Left || self.imageOrientation == UIImageOrientation.LeftMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
}
if ( self.imageOrientation == UIImageOrientation.Right || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2));
}
if ( self.imageOrientation == UIImageOrientation.UpMirrored || self.imageOrientation == UIImageOrientation.DownMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
}
if ( self.imageOrientation == UIImageOrientation.LeftMirrored || self.imageOrientation == UIImageOrientation.RightMirrored ) {
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
var ctx: CGContextRef = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform)
if ( self.imageOrientation == UIImageOrientation.Left ||
self.imageOrientation == UIImageOrientation.LeftMirrored ||
self.imageOrientation == UIImageOrientation.Right ||
self.imageOrientation == UIImageOrientation.RightMirrored ) {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
} else {
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
}
// And now we just create a new UIImage from the drawing context and return it
return UIImage(CGImage: CGBitmapContextCreateImage(ctx))!
}
}
Based on MetalHeart2003's earlier work..
Here is an UIImage extension in Swift 2 based on the accepted answer by #Anomie. It uses a clearer switch case. It also takes the optional value returned by CGBitmapContextCreateImage() into consideration.
extension UIImage {
func rotateImageByOrientation() -> UIImage {
// No-op if the orientation is already correct
guard self.imageOrientation != .Up else {
return self
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform = CGAffineTransformIdentity;
switch (self.imageOrientation) {
case .Down, .DownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
case .Left, .LeftMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
case .Right, .RightMirrored:
transform = CGAffineTransformTranslate(transform, 0, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
default:
break
}
switch (self.imageOrientation) {
case .UpMirrored, .DownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
case .LeftMirrored, .RightMirrored:
transform = CGAffineTransformTranslate(transform, self.size.height, 0)
transform = CGAffineTransformScale(transform, -1, 1)
default:
break
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height),
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage).rawValue)
CGContextConcatCTM(ctx, transform)
switch (self.imageOrientation) {
case .Left, .LeftMirrored, .Right, .RightMirrored:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage)
default:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage)
}
// And now we just create a new UIImage from the drawing context
if let cgImage = CGBitmapContextCreateImage(ctx) {
return UIImage(CGImage: cgImage)
} else {
return self
}
}
}
I have experienced this issue with images taken from camera or saved in camera roll which are taken from camera. Images downloaded in photo library from safari browser does not rotate when uploaded.
I was able to solve this issue by making the image data as JPEG before uploading.
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let data = UIImageJPEGRepresentation(image, 1.0)
We can now use the data for uploading and the image will not get rotated after upload.
Hope this will work.
If I understand, what you want to do is disregard the orientation of the UIImage? If so then you could do this:-
//image is your original image
image = [UIImage imageWithCGImage:[image CGImage]
scale:[image scale]
orientation: UIImageOrientationUp];
or in Swift :-
image = UIImage(CGImage: image.CGImage!, scale: image.scale, orientation:.Up)
It solved my cropping issue.. Hope, this is what you're looking for..
Swift 3 version based on #jake1981 who've taken it from #MetalHeart2003
extension UIImage {
func fixOrientation() -> UIImage {
// No-op if the orientation is already correct
if ( self.imageOrientation == UIImageOrientation.up ) {
return self;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform: CGAffineTransform = CGAffineTransform.identity
if ( self.imageOrientation == UIImageOrientation.down || self.imageOrientation == UIImageOrientation.downMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: self.size.height)
transform = transform.rotated(by: CGFloat(M_PI))
}
if ( self.imageOrientation == UIImageOrientation.left || self.imageOrientation == UIImageOrientation.leftMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.rotated(by: CGFloat(M_PI_2))
}
if ( self.imageOrientation == UIImageOrientation.right || self.imageOrientation == UIImageOrientation.rightMirrored ) {
transform = transform.translatedBy(x: 0, y: self.size.height);
transform = transform.rotated(by: CGFloat(-M_PI_2));
}
if ( self.imageOrientation == UIImageOrientation.upMirrored || self.imageOrientation == UIImageOrientation.downMirrored ) {
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
}
if ( self.imageOrientation == UIImageOrientation.leftMirrored || self.imageOrientation == UIImageOrientation.rightMirrored ) {
transform = transform.translatedBy(x: self.size.height, y: 0);
transform = transform.scaledBy(x: -1, y: 1);
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let ctx: CGContext = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height),
bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0,
space: self.cgImage!.colorSpace!,
bitmapInfo: self.cgImage!.bitmapInfo.rawValue)!
ctx.concatenate(transform)
if ( self.imageOrientation == UIImageOrientation.left ||
self.imageOrientation == UIImageOrientation.leftMirrored ||
self.imageOrientation == UIImageOrientation.right ||
self.imageOrientation == UIImageOrientation.rightMirrored ) {
ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width))
} else {
ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
}
// And now we just create a new UIImage from the drawing context and return it
return UIImage(cgImage: ctx.makeImage()!)
}
}
#an0, thanks for the answer!
The only thing is autoreleasepool:
func fixOrientation(img: UIImage) -> UIImage? {
let result: UIImage?
if img.imageOrientation == .up {
result = img
} else {
result = autoreleasepool { () -> UIImage? in
UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
img.draw(in: rect)
let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return normalizedImage
}
}
return result
}
Here is the Swift-4.2 code for automatic fix your image orientation
Returns UIImage
func AutofixImageOrientation(_ image: UIImage)->UIImage {
UIGraphicsBeginImageContext(image.size)
image.draw(at: .zero)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage ?? image
}
I transposed this into Xamarin:
private static UIImage FixImageOrientation(UIImage image)
{
if (image.Orientation == UIImageOrientation.Up)
{
return image;
}
var transform = CGAffineTransform.MakeIdentity();
float pi = (float)Math.PI;
switch (image.Orientation)
{
case UIImageOrientation.Down:
case UIImageOrientation.DownMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Width, image.Size.Height);
transform = CGAffineTransform.Rotate(transform, pi);
break;
case UIImageOrientation.Left:
case UIImageOrientation.LeftMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
transform = CGAffineTransform.Rotate(transform, pi / 2);
break;
case UIImageOrientation.Right:
case UIImageOrientation.RightMirrored:
transform = CGAffineTransform.Translate(transform, 0, image.Size.Height);
transform = CGAffineTransform.Rotate(transform, -(pi / 2));
break;
}
switch (image.Orientation)
{
case UIImageOrientation.UpMirrored:
case UIImageOrientation.DownMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
transform = CGAffineTransform.Scale(transform, -1, 1);
break;
case UIImageOrientation.LeftMirrored:
case UIImageOrientation.RightMirrored:
transform = CGAffineTransform.Translate(transform, image.Size.Height, 0);
transform = CGAffineTransform.Scale(transform, -1, 1);
break;
}
var ctx = new CGBitmapContext(null, (nint)image.Size.Width, (nint)image.Size.Height, image.CGImage.BitsPerComponent,
image.CGImage.BytesPerRow, image.CGImage.ColorSpace, image.CGImage.BitmapInfo);
ctx.ConcatCTM(transform);
switch (image.Orientation)
{
case UIImageOrientation.Left:
case UIImageOrientation.LeftMirrored:
case UIImageOrientation.Right:
case UIImageOrientation.RightMirrored:
ctx.DrawImage(new CGRect(0, 0, image.Size.Height, image.Size.Width), image.CGImage);
break;
default:
ctx.DrawImage(new CGRect(0, 0, image.Size.Width, image.Size.Height), image.CGImage);
break;
}
var cgimg = ctx.ToImage();
var img = new UIImage(cgimg);
ctx.Dispose();
ctx = null;
cgimg.Dispose();
cgimg = null;
return img;
}

AVFoundation Image orientation off by 90 degrees in the preview but fine in Camera roll

Something really strange is happening, I am trying to capture an image using AVFoundation, the Camera roll image seems just fine, but the image preview has the image rotated by 90 degrees.
This is the code I am using to capture an image
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in stillImageOutput.connections)
{
for (AVCaptureInputPort *port in [connection inputPorts])
{
if ([[port mediaType] isEqual:AVMediaTypeVideo] )
{
videoConnection = connection;
break;
}
}
if (videoConnection)
{
break;
}
}
//NSLog(#"about to request a capture from: %#", stillImageOutput);
[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
CFDictionaryRef exifAttachments = CMGetAttachment( imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
if (exifAttachments)
{
// Do something with the attachments.
//NSLog(#"attachements: %#", exifAttachments);
} else {
NSLog(#"no attachments");
}
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
self.vImage.image = image;
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}];
yes ,it happens when you capture image in Portrait orientation of your device and use that image in your application, because the default orientation of image is Landscape in any IOS Device, so you need to change the orientation of image after picking from Gallery to use in your app.
I have put code to achieve this
Objective-C code
- (UIImage *)fixOrientationOfImage:(UIImage *)image {
// No-op if the orientation is already correct
if (image.imageOrientation == UIImageOrientationUp) return image;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (image.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, image.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}
switch (image.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, image.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationUp:
case UIImageOrientationDown:
case UIImageOrientationLeft:
case UIImageOrientationRight:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, image.size.width, image.size.height,
CGImageGetBitsPerComponent(image.CGImage), 0,
CGImageGetColorSpace(image.CGImage),
CGImageGetBitmapInfo(image.CGImage));
CGContextConcatCTM(ctx, transform);
switch (image.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,image.size.height,image.size.width), image.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,image.size.width,image.size.height), image.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
Swift code
func fixOrientationOfImage(image: UIImage) -> UIImage? {
if image.imageOrientation == .Up {
return image
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform = CGAffineTransformIdentity
switch image.imageOrientation {
case .Down, .DownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
case .Left, .LeftMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
case .Right, .RightMirrored:
transform = CGAffineTransformTranslate(transform, 0, image.size.height)
transform = CGAffineTransformRotate(transform, -CGFloat(M_PI_2))
default:
break
}
switch image.imageOrientation {
case .UpMirrored, .DownMirrored:
transform = CGAffineTransformTranslate(transform, image.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
case .LeftMirrored, .RightMirrored:
transform = CGAffineTransformTranslate(transform, image.size.height, 0)
transform = CGAffineTransformScale(transform, -1, 1)
default:
break
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
guard let context = CGBitmapContextCreate(nil, Int(image.size.width), Int(image.size.height), CGImageGetBitsPerComponent(image.CGImage), 0, CGImageGetColorSpace(image.CGImage), CGImageGetBitmapInfo(image.CGImage).rawValue) else {
return nil
}
CGContextConcatCTM(context, transform)
switch image.imageOrientation {
case .Left, .LeftMirrored, .Right, .RightMirrored:
CGContextDrawImage(context, CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width), image.CGImage)
default:
CGContextDrawImage(context, CGRect(origin: .zero, size: image.size), image.CGImage)
}
// And now we just create a new UIImage from the drawing context
guard let CGImage = CGBitmapContextCreateImage(context) else {
return nil
}
return UIImage(CGImage: CGImage)
}
Swift 3.0
func fixOrientationOfImage(image: UIImage) -> UIImage? {
if image.imageOrientation == .up {
return image
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform = CGAffineTransform.identity
switch image.imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: image.size.width, y: image.size.height)
transform = transform.rotated(by: CGFloat(Double.pi))
case .left, .leftMirrored:
transform = transform.translatedBy(x: image.size.width, y: 0)
transform = transform.rotated(by: CGFloat(Double.pi / 2))
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: image.size.height)
transform = transform.rotated(by: -CGFloat(Double.pi / 2))
default:
break
}
switch image.imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: image.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: image.size.height, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
default:
break
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
guard let context = CGContext(data: nil, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: image.cgImage!.bitsPerComponent, bytesPerRow: 0, space: image.cgImage!.colorSpace!, bitmapInfo: image.cgImage!.bitmapInfo.rawValue) else {
return nil
}
context.concatenate(transform)
switch image.imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
context.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width))
default:
context.draw(image.cgImage!, in: CGRect(origin: .zero, size: image.size))
}
// And now we just create a new UIImage from the drawing context
guard let CGImage = context.makeImage() else {
return nil
}
return UIImage(cgImage: CGImage)
}
Swift 5.5 +
you should set the orientation of the output before you capture the image.
// set the image orientation in output
if let photoOutputConnection = self.photoOutput.connection(with: .video) {
photoOutputConnection.videoOrientation = videoPreviewLayerOrientation!
}
self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureProcessor) // capture image
The accepted answer works, but is much more complicated than it needs to be. You can use the following to rotate the image.
- (UIImage *)cropImage:(UIImage*)image toRect:(CGRect)rect {
CGFloat (^rad)(CGFloat) = ^CGFloat(CGFloat deg) {
return deg / 180.0f * (CGFloat) M_PI;
};
// determine the orientation of the image and apply a transformation to the crop rectangle to shift it to the correct position
CGAffineTransform rectTransform;
switch (image.imageOrientation) {
case UIImageOrientationLeft:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -image.size.height);
break;
case UIImageOrientationRight:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -image.size.width, 0);
break;
case UIImageOrientationDown:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -image.size.width, -image.size.height);
break;
default:
rectTransform = CGAffineTransformIdentity;
};
// adjust the transformation scale based on the image scale
rectTransform = CGAffineTransformScale(rectTransform, image.scale, image.scale);
// apply the transformation to the rect to create a new, shifted rect
CGRect transformedCropSquare = CGRectApplyAffineTransform(rect, rectTransform);
// use the rect to crop the image
CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, transformedCropSquare);
// create a new UIImage and set the scale and orientation appropriately
UIImage *result = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation];
// memory cleanup
CGImageRelease(imageRef);
return result;
}
To just rotate the image and not crop, you can simply call it like this:
UIImage *image;
[self cropImage:image toRect:rect.bounds];
Dipen Panchasara's answer is great, but there could be one problem with it. When you process big images (for example from iPhoneX) there will be massive memory peak which can be an issue in some cases.
So, maybe you want to change that line:
context.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width))
for something with some memory optimization. For example, that will break image drawing in 16 (4*4) steps, which decrease memory consumption significantly:
let partInAxis: CGFloat = 4
let partWidth = image.size.height/partInAxis
let partHeight = image.size.width/partInAxis
for i in 0...Int(partInAxis)-1 {
for j in 0...Int(partInAxis)-1 {
let partialImage = image.cgImage?.cropping(to: CGRect(x: CGFloat(i)*partWidth, y: CGFloat(j)*partHeight, width: partWidth, height: partHeight))
context.draw(partialImage!, in: CGRect(x: CGFloat(i)*partWidth, y: CGFloat(Int(partInAxis)-1-j)*partHeight, width: partWidth, height: partHeight))
}
}
Be aware, that in this case height and width of image must be divided by 4.
I'd recommend using Yodagama's answer, since it's a one-liner and much cleaner. However, if you need to correct the orientation in another way, here's Dipen's answer without forced optionals, as a UIImage extension. For better memory optimization, mix it with this answer.
extension UIImage {
var fixedOrientation: UIImage? {
if imageOrientation == .up {
return self
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
var transform = CGAffineTransform.identity
switch imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: size.width, y: size.height)
transform = transform.rotated(by: .pi)
case .left, .leftMirrored:
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.rotated(by: .pi / 2)
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: size.height)
transform = transform.rotated(by: -.pi / 2)
default: 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)
default: break
}
guard let cgImage = cgImage,
let colorSpace = cgImage.colorSpace else {
return nil
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
let context = CGContext(
data: nil,
width: Int(size.width),
height: Int(size.height),
bitsPerComponent: cgImage.bitsPerComponent,
bytesPerRow: 0,
space: colorSpace,
bitmapInfo: cgImage.bitmapInfo.rawValue
)
guard let context = context else {
return nil
}
context.concatenate(transform)
switch imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
context.draw(cgImage, in: .init(x: 0, y: 0, width: size.height, height: size.width))
default:
context.draw(cgImage, in: .init(origin: .zero, size: size))
}
// And now we just create a new UIImage from the drawing context
guard let newCgImage = context.makeImage() else {
return nil
}
return .init(cgImage: newCgImage)
}
}

Resources