Skip to main content

iOS UIImagePickerController result image orientation after upload



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.


Comments

  1. 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;
    }

    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;
    }

    // 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

    ReplyDelete

Post a Comment

Popular posts from this blog

Slow Android emulator

I have a 2.67 GHz Celeron processor, 1.21 GB of RAM on a x86 Windows XP Professional machine. My understanding is that the Android emulator should start fairly quickly on such a machine, but for me it does not. I have followed all instructions in setting up the IDE, SDKs, JDKs and such and have had some success in staring the emulator quickly but is very particulary. How can I, if possible, fix this problem?

CCNA 1 Final Exam 2011 latest (hot hot hot)

  Hi! I have been posted content of ccna1 final exam (latest and only question.) I will post the answer and insert image on sunday. If you care, please subscribe your email an become a first person have full test content. Subcribe now  Some question  have not content because this question have images content. So that can you wait for me? SUNDAY 1. A user sees the command prompt: Router(config-if)# . What task can be performed at this mode? Reload the device. Perform basic tests. Configure individual interfaces. Configure individual terminal lines. 2. Refer to the exhibit. Host A attempts to establish a TCP/IP session with host C. During this attempt, a frame was captured with the source MAC address 0050.7320.D632 and the destination MAC address 0030.8517.44C4. The packet inside the captured frame has an IP source address 192.168.7.5, and the destination IP address is 192.168.219.24. At which point in the network was this packet captured? leaving host A leaving ATL leaving...

Java Urban Myths

Along the line of C++ Urban Myths and Perl Myths : What are the Java Urban Myths? That is, the ideas and conceptions about Java that are common but have no actual roots in reality . As a Java programmer, what ideas held by your fellow Java programmers have you had to disprove so often that you've come to believe they all learned at the feet of the same drunk old story-teller? Ideally, you would express these myths in a single sentence, and include an explanation of why they are false.