title: iOS: Cropping a still image grabbed from a UIImagePickerController camera with overlay
body: <p>I am new to iOS and I have been bashing head against the wall for this for the past week looking around online for tutorials such as: <a href="http://niftybean.com/main/blog/16-selecting-regions-from-rotated-exif-images-on-iphone" rel="nofollow noreferrer">Dealing with Exif Images</a>, <a href="https://stackoverflow.com/questions/1260249/resizing-uiimages-pulled-from-the-camera-also-rotates-the-uiimage">Resizing images</a>, and many more random questions here on StackOverflow. From these, I figured that <code>>=iOS 4.0</code>, all images taken from the camera contain <code>EXIF</code>-based rotation information.</p>
  
  <p><strong>What's not working:</strong> After trying different image cropping techniques, all I end up with is cropping of the image at some random corners and also, the resulting image appears to be zoomed in :( When I use a <code>png</code> image from the internet (which don't contain EXIF data), the cropping is working. By random corners, I mean - the image ends up being cropped at the top-right/top-left and zoomed-in.</p>
  
  <p><strong>What I am trying to accomplish:</strong> <br>
  I am trying to crop an image <code>100 px</code> from top and <code>100 px</code> from bottom. Essentially, I am using two overlay strips - 1 at the top, and 1 at the bottom with the  <code>CGRect(0.0, 0.0, SCREEN_WIDTH, 100.0)</code> [a <code>100.0 px</code> tall strip at the top] and another <code>CGRect(0.0, SCREEN_HEIGHT - 100, SCREEN_WIDTH, 100.0)</code> [another <code> 100 px</code> tall strip at the bottom]. I need to get the image between these two strips: I assume the height of the image is: <code>SCREEN_HEIGHT - 200.0</code>.</p>
  
  <p><strong>Displaying UIImagePickerController for camera with overlay:</strong></p>
  
  <pre>
  <code>
      //SCREEN_HEIGHT = 480 and SCREEN_WIDTH = 320
      UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
  
      if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO) 
      {
          NSLog(@"Camera not available");
          return;
      }
  
      imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
      imagePicker.delegate = self;
      imagePicker.allowsEditing = NO;
  
  
      // Hide the controls
      imagePicker.showsCameraControls = NO;
      imagePicker.navigationBarHidden = YES;
  
      // Make camera view full screen
      imagePicker.wantsFullScreenLayout = YES;
      //imagePicker.cameraViewTransform = CGAffineTransformScale(imagePicker.cameraViewTransform, CAMERA_TRANSFORM_X, CAMERA_TRANSFORM_Y);
  
  
      //Overlay
      //OverlayView is a plain UIView with the CGRects mentioned in the question.
      OverlayView *overlay = [[OverlayView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)]; 
      [overlay initOverlay:self];
      imagePicker.cameraOverlayView = overlay;
      [self presentModalViewController:imagePicker animated:YES];
  </code>
  </pre>
  
  <p><strong>Code to rotate image based on EXIF <code>imageOrientation</code> property and cropping it</strong></p>
  
  <pre>
  <code>
  - (UIImage *) cropImage: (UIImage *) originalImage 
  {
  
      CGRect cropRect = CGRectMake(0, 100.0, SCREEN_WIDTH, SCREEN_HEIGHT - 100);
  
      CGRect transformedRect = [self TransformCGRectForUIImageOrientation:cropRect :originalImage.imageOrientation :originalImage.size];
  
      CGImageRef resultImageRef = CGImageCreateWithImageInRect(originalImage.CGImage, transformedRect);
  
      UIImage *newImage = [[[UIImage alloc] initWithCGImage:resultImageRef scale:1.0 orientation:originalImage.imageOrientation] autorelease];
  
      return newImage;
  }
  
  - (CGRect) TransformCGRectForUIImageOrientation: (CGRect) source: (UIImageOrientation) orientation: (CGSize) imageSize {
  
      switch (orientation) {
          case UIImageOrientationLeft: { // EXIF #8
              CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(
                                                                               imageSize.height, 0.0);
              CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,
                                                                     M_PI_2);
              return CGRectApplyAffineTransform(source, txCompound);
          }
          case UIImageOrientationDown: { // EXIF #3
              CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(
                                                                               imageSize.width, imageSize.height);
              CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,
                                                                     M_PI);
              return CGRectApplyAffineTransform(source, txCompound);
          }
          case UIImageOrientationRight: { // EXIF #6
              CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(
                                                                               0.0, imageSize.width);
              CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,
                                                                     M_PI + M_PI_2);
              return CGRectApplyAffineTransform(source, txCompound);
          }
          case UIImageOrientationUp: // EXIF #1 - do nothing
          default: // EXIF 2,4,5,7 - ignore
              return source;
      }
  
  </code>
  </pre>
  
  <p>The <code>cropImage</code> method seems to work for images downloaded from the internet (which don't contain any orientation info).
  I am running out of options. Could someone PLEASE help me out? </p>
  
  <p>Thanks for reading! </p>