UIImagePickerController bug

0xSina picture 0xSina · Oct 16, 2013 · Viewed 7.2k times · Source

I think I found a bug in latest iOS 7 by running an app with Base SDK set to iOS 6.1 (possibly even lower versions too, haven't tested that out yet)

I have this image in my photo library: http://i.imgur.com/7KUIGLt.jpg

I present a UIImagePickerController via:

UIImagePickerController *vc = [[UIImagePickerController alloc] init];
vc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
vc.delegate = self;
vc.allowsEditing = YES;
[self presentViewController:vc animated:YES completion:nil];

I save the chosen image to my desktop (I am running this on simulator, but this works on device too)

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    UIImage* outputImage = [info objectForKey:UIImagePickerControllerEditedImage];
    if (outputImage == nil) {
        outputImage = [info objectForKey:UIImagePickerControllerOriginalImage];
    }
    NSData *d = UIImagePNGRepresentation(outputImage);
    [d writeToFile:@"/Users/Admin/Desktop/test.png" atomically:YES];
    [self dismissViewControllerAnimated:YES completion:nil];
}

This is the resulting image: enter image description here

Notice the big black bar to the right. What's causing this?

To reproduce this, you need:

  • iOS 7
  • App with Base SDK set to 6.1 (maybe even lower SDKs too, i haven't tried yet)
  • iPhone 5/5c/5s
  • Only happens to pictures that were taken with iPhone 5/5c/5s camera (you can use the original image I linked above for testing)

NOTE: Just to be clear, the black bar is part of the actual image. The image you see there is not a screenshot of a UIImageView, but the actual image saved to disk and uploaded here...

Answer

Segev picture Segev · Oct 20, 2013

Your question is "What's causing this?" So I'll focus on that instead of giving a workaround. This is definitely a bug in iOS 7 dealing with edited images in lower base SDKs. We can also rule out that XCode 5 & Base SDK 6.1 causing this because I'm getting the same issue with XCode 4.6.3 & 6.1 SDK running on iOS 7 Simulator.

The source of the problem is that the CropRect values that are calculated by the SDK are wrong. If you'll print out the info NSDictionary from imagePickerController:didFinishPickingMediaWithInfo you'll see that:

iOS 7 running any SDK lower than 7 we'll get:

UIImagePickerControllerCropRect = "NSRect: {{154, 495}, {1705, 1705}}";

While running iOS 6 or 5 with their SDK will give us:

UIImagePickerControllerCropRect = "NSRect: {{0, 149}, {1704, 1705}}";

You're probably saying, hmm, those y values are changing between SDKs too. Well, yea, if you'll slide your pic all the way down and select it you'll also get a black bar at the bottom of the picture.

enter image description here

Suggested Solutions:

  1. File a bug report to Apple here ...Did that!

  2. Don't use UIImagePickerControllerEditedImage and take the original picture instead.

  3. Calculate and do the cropping your self.

  4. Use a 3rd party cropping library such as PEPhotoCropEditor or SSPhotoCropperViewController


Edit - very simple solution added by fan of the answer!

Amazingly, it can be this simple and elegant to crop it yourself:

{
// There is a bug in iOS. When using ALBUM, you must crop it yourself:

fromAlbum = [info objectForKey:UIImagePickerControllerOriginalImage];
fromAlbum = [fromAlbum fixOrientation];

CGRect crop = [[info valueForKey:@"UIImagePickerControllerCropRect"] CGRectValue];
fromAlbum = [self ordinaryCrop:fromAlbum toRect:crop];
}

Here's the whole routine ordinaryCrop:toRect:

-(UIImage *)ordinaryCrop:(UIImage *)imageToCrop toRect:(CGRect)cropRect
 {
 CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], cropRect);
 UIImage *cropped = [UIImage imageWithCGImage:imageRef];
 CGImageRelease(imageRef);
 return cropped;
 }

Now as Jesse points out, it is critical to rotate the image properly. This absolutely incredible piece of code by Anomie does the job:

iOS UIImagePickerController result image orientation after upload

Fixing UIImage orientation .. UIImage+fixOrientation.h

It's that simple, hope it helps someone. Thanks again for the priceless answers here.