UIImagePickerController pixelated image from choosing too quickly, before image fully loaded

520 views Asked by At

I am using UIImagePickerController in an iOS app to save an image in context using UIGraphicsBeginImageContext/UIGraphicsBeginImageContextWithOptions.

I recently noticed that I picture I had saved and then displayed at a later date was highly pixelated; when I went back with the same code and imported the photo again, I got a great image. After playing with this for a while on my device, I figured out that the quality of the image saved depends on WHEN I pressed the 'Choose' button on the 'Move and Scale' screen.

If the image is a larger image and still loading when I press the button, the image is pixelated... if I wait until the image loads, it is fine. My question is, is there any way I can control when the user presses the 'Choose' button - is there any way to force them to wait until after the image is fully loaded? Or is there another way that would be better to approach this issue?

- (void)choosePhoto {

    //NSLog(@"%s", __FUNCTION__);
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    imagePicker.delegate = self;
    imagePicker.allowsEditing = YES;

    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    [self presentModalViewController:imagePicker animated:YES];
    [imagePicker release];
}

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

    //NSLog(@"%s", __FUNCTION__);
    [self dismissModalViewControllerAnimated:YES];

    UIImage *pickedImage = (UIImage*)[info objectForKey:@"UIImagePickerControllerEditedImage"];
    [self setPersonImage:pickedImage];
}


- (void) setPersonImage:(UIImage *)pickedImage  {

    //NSLog(@"%s", __FUNCTION__);

    NSManagedObjectContext *context = [[UIApplication sharedDelegate] managedObjectContext];
    PersonImage *oldImage = person.image;
    if (oldImage != nil) {
        [context deleteObject:(NSManagedObject*)oldImage];
    }

    if (pickedImage != nil) {
        // Create an image object for the new image.
        PersonImage *newImageObject = [NSEntityDescription insertNewObjectForEntityForName:@"PersonImage" inManagedObjectContext:context];
        [newImageObject setImage:pickedImage]; 
        [person setImage:newImageObject]; 
    }
    else {
        [person setImage:nil];
    }

    NSError *error;
    if (![context save:&error]) {
        exit(-1);  // Fail
    }
}
2

There are 2 answers

0
sgosha On BEST ANSWER

I suggest you implement your own Crop&Resize view controller.

  1. set imagePicker.allowsEditing = NO.
  2. create your view controller in - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info and pass selected image to your view controller.
  3. push your view controller to image picker: [picker pushViewController:yourVC animated:YES]
5
Akshay On

The image captured by the iPhone 4 camera is ~5 MB in size and it takes a while to display/render it. One option is to compress the image using UIImageJPEGRepresentation().

If you do not want to compress the image, you can use UIWebView to display the images. The UIWebViewDelegate has a method - (void)webViewDidFinishLoad:(UIWebView *)webView, that hits after the rendering has been completed. You can enable the choose button in this method (which is disabled initially).