9

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
  • 3,829
  • 7
  • 38
  • 73

3 Answers3

10

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];
}
Rok Jarc
  • 18,765
  • 9
  • 69
  • 124
  • 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 – Adam Bardon Sep 21 '13 at 12:05
  • 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 Sep 21 '13 at 12:10
  • App shouldn't crash even if edited image was `nil` so there is probably a problem elsewhere in the code. – Rok Jarc Sep 21 '13 at 12:12
  • 1
    allowsEditing is set to YES, and UIImagePickerControllerEditedImage is nil – Adam Bardon Sep 21 '13 at 12:21
  • Do you by any chance dismiss the controller before you set the image? – Rok Jarc Sep 21 '13 at 12:23
  • I dismiss the controller at the end of didFInishPIckingMediaWithInfo method (which is basically the one from apple's sample code, just slightly edited) – Adam Bardon Sep 21 '13 at 12:30
  • Strange. Try expanding your question a bit, post some code (possibly with exact crash location). – Rok Jarc Sep 21 '13 at 12:32
  • ok, my bad, crash was caused most probably by UIImage *image = [info valueForKey:UIImagePickerControllerEditedImage]; [self.capturedImages addObject:image]; – Adam Bardon Sep 21 '13 at 12:38
  • 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? – Adam Bardon Sep 21 '13 at 13:02
  • 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. – Rok Jarc Sep 21 '13 at 13:33
  • 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 – Adam Bardon Sep 21 '13 at 13:35
  • check this answer: http://stackoverflow.com/a/4192109/653513 seems crazy but it might work – Rok Jarc Sep 21 '13 at 13:41
  • 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... – Adam Bardon Sep 21 '13 at 17:24
  • Have you tried dismissing picker before taking the image from info. That is suggested in the linked answer. – Rok Jarc Sep 21 '13 at 18:14
  • 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 Sep 21 '13 at 20:53
9

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.

Wim Haanstra
  • 5,918
  • 5
  • 41
  • 57
5

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?

Adam Bardon
  • 3,829
  • 7
  • 38
  • 73