UIImage in iOS 5, Orientation and Resize

November 7, 2011

One of the things I found very strange is the fact that most operations that came with iOS prior iOS 5 which revolved around UIImage didn’t take into account the orientation of the image. This meant that if you want to read a picture from the camera roll and resize it, you’d have to roll your own code to correctly flip and/or rotate the image according to its orientation value.

Being my lazy self I used the fine code of Trevor Harmon in UIImage+Resize. Trevor added some categories to make handling UIImage a bit nicer. The code takes create of everything including orientation.

My app worked great on iOS 4 and early betas of iOS 5, however in the late beta of iOS 5 and in the release it wrongfully rotated the images.

After further investigation it seems iOS 5 already rotates the image correctly. UIImage+Resize rotated it again, causing the images to get skewed.
A quick fix would simply avoid the transposition code in UIImage+Resize.

Since the code ran perfectly fine in iOS 4, for backwards compatibility I added a check for OS version and for anything below 5.0 the old code would work.
Check out this gist:

For better performance I would store a boolean flag somewhere in the app saying you are running in iOS 5 and check that instead of keep on checking the OS version every run, but this is just to get you started.

Be Sociable, Share!

tags: , , , , ,
posted in Code, Tips n' Tricks by Eran Sandler

Follow comments via the RSS Feed | Leave a comment | Trackback URL

  • Al

    I’m not seeing this behavior on iOs 5.0.1 and this fix was actually causing images to NOT be rotated correctly in my testing. Could you clarify exactly what you mean by the “image is already rotated”?

    The way the resize code works is that it effectively copies the cglayer of the the UIImage to a new bitmap. So, in the case where UIImage is correctly oriented to begin with, image.imageOrientation will be 0 and you can copy from the cglayer to the bitmap directly. But, if image.imageOrientation is not 0, it seems that you must apply some transformation for the resulting bitmap to be oriented correctly.

    So, are you saying that in your testing image.imageOrientation is always 0 on ios5? Or, are you saying that in the case where image.imageOrientation is non-zero, the cglayer is still oriented correctly, so you don’t need to apply a transform on the copy? Or, are you saying something else entirely? Thanks!

  • http://eran.sandler.co.il/ Eran Sandler

    The problem was mostly in versions prior to iOS 5.0. The code is here to support both methods, in which case version 5.0 and above shouldn’t draw the image transposed and would just leave it as it is when resizing it.

    As you can see in the code, I don’t draw the image transposed for iOS 5.0 and above. The code might have an issue with the 5.0.1 version when converting the version to a float value.

  • tomandersen

    On 5.1 I have trouble with your code as is. I am finding that if I comment out the transform elimination, it works. This is on 5.1.1 on iPhone 4 hardware. I am not sure what is going on.

  • daniel

    Same problem here. But I haven’t figured out how to fix it yet. I end up with skewed and wrongly rotated photos. I also take the image data, store it in nsdata and then load it again.

  • tomandersen

    // if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) {
    // // Apprently in iOS 5 the image is already correctly rotated, so we don’t need to rotate it manually
    // drawTransposed = NO;
    // } else {
    switch (self.imageOrientation) {
    case UIImageOrientationLeft:
    case UIImageOrientationLeftMirrored:
    case UIImageOrientationRight:
    case UIImageOrientationRightMirrored:
    drawTransposed = YES;
    break;

    default:
    drawTransposed = NO;
    }

    transform = [self transformForOrientation:newSize];
    }

    Is what I meant by commenting out the IOS 5 stuff…

    –Tom

Switch to our mobile site

 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org