How to crop UIImagePickerController taken picture as it is on display

20,323

Solution 1

Just posting this as an answer, but I am not sure if the poster asks for the edited image.

When you take a picture with the UIImagePickerController, the picker shows only part of the image that is actually captured when taking the photo, like shown in the picture below where the black lines are the screen of the iPhone.

enter image description here

The image you get from the camera is the full size image, but on screen is only the center of the image, with either the width or the height of the image maxed out to the screen size.

All you need to do is get the center from the image like shown above and you have the exact image you had on your screen.

Solution 2

You can get the original or cropped image depending on the key for info dictionary.

The pickedImageEdited would be the cropped image you are looking for and pickedImageOriginal would be the full original image.

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *pickedImageOriginal = [info objectForKey:UIImagePickerControllerOriginalImage];

    UIImage *pickedImageEdited = [info objectForKey:UIImagePickerControllerEditedImage];

    //do your stuff

    [self dismissViewControllerAnimated:YES completion:nil];
}

Solution 3

After Wim's answer, I was able to come up with solution like this:

UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];

UIGraphicsBeginImageContext(CGSizeMake(720, 960));
[image drawInRect: CGRectMake(0, 0, 720, 960)];
UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

CGRect cropRect = CGRectMake(40, 0, 640, 960);

CGImageRef imageRef = CGImageCreateWithImageInRect([smallImage CGImage], cropRect);
[self.imageView setImage:[UIImage imageWithCGImage:imageRef]];

As you can see, this is made for 3,5" iPhone screen, and it seems to work, but code is device-dependent, or is there better solution?

Share:
20,323
Adam Bardon
Author by

Adam Bardon

Creator of ioscookies.com - a hand curated collection of iOS libraries written in Swift, presetbrewery.com - a drag-n-drop tool for converting Lightroom presets to Adobe Camera Raw, boxiqq.co - a platform to create beautiful and customizable dashboards

Updated on July 14, 2022

Comments

  • Adam Bardon
    Adam Bardon almost 2 years

    When I take photo using UIImagePickerController, there is more picture than was visible on screen... How can I take photo/crop it, so that it's exactly the same as I saw on screen?

    edit: I'll add code, to specify my problem:

    - (void)showImagePickerForSourceType:(UIImagePickerControllerSourceType)sourceType
    {
    
    UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
    imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
    imagePickerController.sourceType = sourceType;
    imagePickerController.delegate = self;
    imagePickerController.showsCameraControls = NO;
    imagePickerController.allowsEditing = YES;
    
    if (sourceType == UIImagePickerControllerSourceTypeCamera)
    {
        [[NSBundle mainBundle] loadNibNamed:@"OverlayView" owner:self options:nil];
        self.overlayView.frame = imagePickerController.cameraOverlayView.frame;
        imagePickerController.cameraOverlayView = self.overlayView;
        //self.overlayView = nil;
        self.overlayImage.image = self.imageView.image;
        self.overlayImage.alpha = 0.5;
    
        UISlider *slider=[[UISlider alloc]initWithFrame:CGRectMake(60, 80, 200, 30)];
        [slider setMaximumValue:1.0];
        [slider setMinimumValue:0.0];
        [slider setValue:0.5];
        [slider addTarget:self action:@selector(sliderChanged:)  forControlEvents:UIControlEventValueChanged];
    
        if (self.working == TRUE)
        {
            [imagePickerController.cameraOverlayView addSubview:self.overlayImage];
            [imagePickerController.cameraOverlayView addSubview:slider];
        }
    }
    
    self.imagePickerController = imagePickerController;
    [self presentViewController:self.imagePickerController animated:YES completion:nil];
    }
    

    didFinishPickingMediaWithInfo:

    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
    [self dismissViewControllerAnimated:YES completion:NULL];
    
    //this works, image is displayed
    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
    //this doesn't work, image is nil
    UIImage *image = [info objecyForKey:UIImagePickerControllerEditedImage];    
    
    [self.imageView setImage:image];
    self.working = TRUE;
    
    self.imagePickerController = nil;
    //[self dismissViewControllerAnimated:YES completion:NULL];
    }
    

    Can I use UIImagePickerControllerEditedImage, when imagePickerController.showsCameraControls = NO;?

  • Adam Bardon
    Adam Bardon almost 11 years
    thanks for reply, I've tried to use UIImagePickerControllerEditedImage, then I'll assign it to UIImageView so I can display it, but for some reason when showing that imageView, app crashes... whereas when I'm using UIImagePickerControllerOriginalImage it works ok
  • Rok Jarc
    Rok Jarc almost 11 years
    Do you have some more crash information? Do you have controller's allowsEditing set to YES? I use this code in many apps with no problems whatsoever.
  • Rok Jarc
    Rok Jarc almost 11 years
    App shouldn't crash even if edited image was nil so there is probably a problem elsewhere in the code.
  • Adam Bardon
    Adam Bardon almost 11 years
    allowsEditing is set to YES, and UIImagePickerControllerEditedImage is nil
  • Rok Jarc
    Rok Jarc almost 11 years
    Do you by any chance dismiss the controller before you set the image?
  • Adam Bardon
    Adam Bardon almost 11 years
    I dismiss the controller at the end of didFInishPIckingMediaWithInfo method (which is basically the one from apple's sample code, just slightly edited)
  • Rok Jarc
    Rok Jarc almost 11 years
    Strange. Try expanding your question a bit, post some code (possibly with exact crash location).
  • Adam Bardon
    Adam Bardon almost 11 years
    ok, my bad, crash was caused most probably by UIImage *image = [info valueForKey:UIImagePickerControllerEditedImage]; [self.capturedImages addObject:image];
  • Adam Bardon
    Adam Bardon almost 11 years
    thanks for help :) I've used apple's sample code, and left few things as it was, even though I didn't needed it, so that was a mistake... anyway now when I assign UIImagePickerControllerOriginalImage to UIImage, nothing is displayed... is it possible that it'd be nil?
  • Rok Jarc
    Rok Jarc almost 11 years
    it shouldn't be nil. you can always check with if (![info objectForKey:UIImagePickerControllerOriginalImage]) NSLog (@"it's NIL"); but probably your IBOutlet (if you use IB) is not properly connected or you don't assign the new image to some UIImageView object.image or the UIImageView object is not added to the viewcontroller's view.
  • Adam Bardon
    Adam Bardon almost 11 years
    when I use UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; it works perfectly, so everything should be set ok, after changing to UIImage *image = [info valueForKey:UIImagePickerControllerEditedImage]; image is not displayed
  • Rok Jarc
    Rok Jarc almost 11 years
    check this answer: stackoverflow.com/a/4192109/653513 seems crazy but it might work
  • Adam Bardon
    Adam Bardon almost 11 years
    even using ALAssetsLibrary as was suggested on that above answer, it doesn't work for me, strange is that they have troubles on simulator, whereas I'm testing it on real device iphone 4s...
  • Rok Jarc
    Rok Jarc almost 11 years
    Have you tried dismissing picker before taking the image from info. That is suggested in the linked answer.
  • Adam Bardon
    Adam Bardon almost 11 years
    from linked answer: The other option that almost assuredly will work is to create a separate file for the image picking code in Xcode and set that file to not use ARC, keeping the solution here. could you give me code how to do that?
  • Adam Bardon
    Adam Bardon almost 11 years
    Hi Wim, thank you for your answer, that's exactly what I was asking for :)
  • Wim Haanstra
    Wim Haanstra over 10 years
    Great, you should mark it as the answer, so that other people can find it.
  • Adam Bardon
    Adam Bardon over 6 years
    Well, adjust the size based on the device.