50

What I want to do is take a snapshot from my camera , send it to a server and then the server sends me back the image on a viewController. If the image is in portrait mode the image appears well on screen , however if the image was taken in landscape mode the image appears streched on the screen(as it tries to appear on portrait mode!). I dont know how to fix this but i guess one solution is first to check if the image is in portrait/landscape mode and then if it is on landscape mode rotate it by 90degrees before showing it on screen. So how could i do that?

IronManGill
  • 7,222
  • 2
  • 31
  • 52
user1511244
  • 725
  • 3
  • 11
  • 15
  • possible duplicate of [iOS UIImagePickerController result image orientation after upload](http://stackoverflow.com/questions/5427656/ios-uiimagepickercontroller-result-image-orientation-after-upload) – Axel Guilmin Apr 03 '15 at 00:11
  • I had the exact same problem and I solved it using the category proposed in this response : http://stackoverflow.com/a/5427890/1327557 It manage all cases (rotations and miroring) – Axel Guilmin Apr 03 '15 at 00:17

14 Answers14

128
self.imageview.transform = CGAffineTransformMakeRotation(M_PI_2);

Swift 4+:

self.imageview.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi/2))
iwasrobbed
  • 46,496
  • 21
  • 150
  • 195
mandeep-dhiman
  • 2,505
  • 2
  • 21
  • 31
  • Isn't `M_PI/2` going to cause an unwanted type casting into an int and subsequent loss of accuracy? – eremzeit Feb 09 '14 at 10:22
  • I found that this rotated my image 45 degrees when using on a regular view – hdost Feb 10 '15 at 14:52
  • 3
    'Double' is not convertible to 'CGFloat' - I got this error cell.arrowImageView?.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2)) - force type cast fix – Dustin Williams Mar 27 '15 at 19:44
30

This is the complete code for rotation of image to any degree just add it to appropriate file ie in .m as below where you want to use the image processing

for .m

@interface UIImage (RotationMethods)
- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees;
@end

@implementation UIImage (RotationMethods)

static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};

- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees 
{   
    // calculate the size of the rotated view's containing box for our drawing space
    UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)];
    CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
    rotatedViewBox.transform = t;
    CGSize rotatedSize = rotatedViewBox.frame.size;

    // Create the bitmap context
    UIGraphicsBeginImageContext(rotatedSize);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();

    // Move the origin to the middle of the image so we will rotate and scale around the center.
    CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);

    //   // Rotate the image context
    CGContextRotateCTM(bitmap, DegreesToRadians(degrees));

    // Now, draw the rotated/scaled image into the context
    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), [self CGImage]);

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;

}

@end

This is the code snippet form apple's SquareCam example.

To call the above method just use the below code

UIImage *rotatedSquareImage = [square imageRotatedByDegrees:rotationDegrees];

Here the square is one UIImage and rotationDegrees is one flote ivar to rotate the image that degrees

Stunner
  • 12,025
  • 12
  • 86
  • 145
The iOSDev
  • 5,237
  • 7
  • 41
  • 78
23

Swift 3 and Swift 4 use .pi instead

eg:

//rotate 90 degrees
myImageView.transform = CGAffineTransform(rotationAngle: .pi / 2)

//rotate 180 degrees
myImageView.transform = CGAffineTransform(rotationAngle: .pi)

//rotate 270 degrees
myImageView.transform = CGAffineTransform(rotationAngle: .pi * 1.5)
Jesus Rodriguez
  • 2,571
  • 2
  • 22
  • 38
14
- (UIImage *)rotateImage:(UIImage*)image byDegree:(CGFloat)degrees 
{   
    UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,image.size.width, image.size.height)];
    CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
    rotatedViewBox.transform = t;
    CGSize rotatedSize = rotatedViewBox.frame.size;
    [rotatedViewBox release];

    UIGraphicsBeginImageContext(rotatedSize);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();


    CGContextTranslateCTM(bitmap, rotatedSize.width, rotatedSize.height);

    CGContextRotateCTM(bitmap, DegreesToRadians(degrees));


    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-image.size.width, -image.size.height, image.size.width, image.size.height), [image CGImage]);

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;

}
janusfidel
  • 8,036
  • 4
  • 30
  • 53
  • This answer lowers image resolution, if image has scale factor. Besides that this is a great answer. Add next code and use width and height variables instead of image.size.width and image.size.height: CGFloat width = image.size.width * image.scale, height = image.size.height * image.scale; – Borzh Apr 11 '17 at 20:23
  • Or easier, use UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, image.scale) instead of UIGraphicsBeginImageContext() – Borzh Apr 11 '17 at 20:33
8

Simply add this code to the image.

Image.transform=CGAffineTransformMakeRotation(M_PI / 2);
IronManGill
  • 7,222
  • 2
  • 31
  • 52
6

I got an error trying this in XCode 6.3 Swift 1.2

self.imageview.transform = CGAffineTransformMakeRotation(M_PI_2);

You should try this to force type cast fix:

self.imageview.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2));

Swift 4 Edit

imageview.transform = CGAffineTransform(rotationAngle: .pi/2)
Matthew Usdin
  • 1,264
  • 1
  • 19
  • 20
3

Swift 3 version:

imageView.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI_2))
Dhruv Khatri
  • 803
  • 6
  • 15
3

Swift 4+.

arrowImageView.transform = CGAffineTransform(rotationAngle: .pi/2)

Note: angle is in radian

.pi = 180 degree

.pi/2 = 90 degree

If you want to add with animation

  @IBAction func applyTransForm(sender: UIButton) {
        sender.isSelected = !sender.isSelected
        UIView.animate(withDuration: 1, animations: {
        if sender.isSelected {
            self.arrowImageView.transform = CGAffineTransform(rotationAngle: .pi)
        } else {
            self.arrowImageView.transform = CGAffineTransform(rotationAngle: 0)

        }
        })
    }

Output:

enter image description here

Community
  • 1
  • 1
Jack
  • 13,571
  • 6
  • 76
  • 98
2

Swift 4 | Xcode 9 syntax (please note that this code rotates a UIImageView 90 degrees clockwise, not a UIImage):

myImageView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi / 2))
Frank Eno
  • 2,581
  • 2
  • 31
  • 54
2
 func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage {

    let size = oldImage.size
    UIGraphicsBeginImageContext(size)

    let bitmap: CGContext = UIGraphicsGetCurrentContext()!
    //Move the origin to the middle of the image so we will rotate and scale around the center.
    bitmap.translateBy(x: size.width / 2, y: size.height / 2)
    //Rotate the image context
    bitmap.rotate(by: (degrees * CGFloat(Double.pi / 180)))
    //Now, draw the rotated/scaled image into the context
    bitmap.scaleBy(x: 1.0, y: -1.0)

    let origin = CGPoint(x: -size.width / 2, y: -size.width / 2)

    bitmap.draw(oldImage.cgImage!, in: CGRect(origin: origin, size: size))

    let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage

}

Use of function

imageRotatedByDegrees(oldImage: yourImage, deg: degree) 
urvashi bhagat
  • 1,123
  • 12
  • 15
1

Doing it in the Image Level, in Swift 5:

extension UIImage{
    
    
    func imageRotated(by radian: CGFloat) -> UIImage{
        
        let rotatedSize = CGRect(origin: .zero, size: size)
            .applying(CGAffineTransform(rotationAngle: radian))
            .integral.size
        UIGraphicsBeginImageContext(rotatedSize)
        if let context = UIGraphicsGetCurrentContext() {
            let origin = CGPoint(x: rotatedSize.width / 2.0,
                                 y: rotatedSize.height / 2.0)
            context.translateBy(x: origin.x, y: origin.y)
            context.rotate(by: radian)
            draw(in: CGRect(x: -origin.y, y: -origin.x,
                            width: size.width, height: size.height))
            let rotatedImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            return rotatedImage ?? self
        }

        return self

    }
}
dengApro
  • 3,848
  • 2
  • 27
  • 41
0

Here is the Swift 2.2 version of The iOSDev answer (in UIImage extension):

func degreesToRadians(degrees: CGFloat) -> CGFloat {
    return degrees * CGFloat(M_PI) / 180
}

func imageRotatedByDegrees(degrees: CGFloat) -> UIImage {
    // calculate the size of the rotated view's containing box for our drawing space
    let rotatedViewBox = UIView(frame: CGRectMake(0,0,self.size.width, self.size.height))
    let t = CGAffineTransformMakeRotation(self.degreesToRadians(degrees))
    rotatedViewBox.transform = t
    let rotatedSize = rotatedViewBox.frame.size

    // Create the bitmap context
    UIGraphicsBeginImageContext(rotatedSize)
    let bitmap = UIGraphicsGetCurrentContext()

    // Move the origin to the middle of the image so we will rotate and scale around the center.
    CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);

    // Now, draw the rotated/scaled image into the context
    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), self.CGImage);

    let newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;

}
Beninho85
  • 3,273
  • 27
  • 22
0

It´s best only use the bitmap. In my case use a UIImage that is in reference.image and I converted image at base64String. Without CGAffineTransformMakeRotation and without rotatedViewBox.transform

var rotatedSize = reference.image.size;
                //Create bitmap context
                UIGraphicsBeginImageContext(rotatedSize);
                var bitmap = UIGraphicsGetCurrentContext();
                //move origin to the middle of the image for rotation
                CGContextTranslateCTM(bitmap, rotatedSize.width / 2, rotatedSize.height / 2);
                //rotate image context
                CGContextRotateCTM(bitmap, 1.5708);
                CGContextDrawImage(bitmap, CGRectMake(-reference.image.size.width / 2, -reference.image.size.height / 2, reference.image.size.width, reference.image.size.height), reference.image.CGImage);
                var rotatedImage = UIGraphicsGetImageFromCurrentImageContext();
                var base64Image = UIImageJPEGRepresentation(rotatedImage, compression).base64EncodedStringWithOptions(0);
                UIGraphicsEndImageContext();
                return base64Image;
0

If you are looking to save image then you need to rotate picture context not the view. I have used provided examples above but they did not work well when centering the image. So I have enhanced and fixed as follows :

func imageRotatedByDegrees(deg degrees: CGFloat) -> UIImage {

    UIGraphicsBeginImageContext(CGSize(width: self.size.height, height: self.size.width))

    let bitmap: CGContext = UIGraphicsGetCurrentContext()!

    // Move the origin to the middle of the image so we will rotate and scale around the center.
    bitmap.translateBy(x: self.size.width / 2, y: self.size.height / 2)

    // Rotate the image context
    bitmap.rotate(by: (degrees * CGFloat(Double.pi / 180)))

    // Now, draw the rotated/scaled image into the context
    bitmap.scaleBy(x: 1.0, y: -1.0)

    let origin = CGPoint(x: -self.size.height / 2, y: -self.size.width / 2)

    bitmap.draw(self.cgImage!, in: CGRect(origin: origin, size: CGSize(width: self.size.width, height: self.size.height)))

    let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!

    UIGraphicsEndImageContext()

    return newImage
}
COzkurt
  • 427
  • 4
  • 4