iOS Custom UIImagePickerController Camera Crop to

2019-01-12 18:59发布

问题:

I'm trying to create a camera like Instagram where the user can see a box and the image would crop to that box. For Some reason the camera doesn't go all the way to the bottom of the screen and cuts off near the end. I'm also wondering how would I go about cropping the image to be 320x320 exactly inside that square?

回答1:

Here's the easiest way to do it (without reimplementing UIImagePickerController). First, use an overlay to make the camera field look square. Here's an example for 3.5" screens (you'd need to update it to work for iPhone 5):

UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = source;

if (source == UIImagePickerControllerSourceTypeCamera) {
    //Create camera overlay
    CGRect f = imagePickerController.view.bounds;
    f.size.height -= imagePickerController.navigationBar.bounds.size.height;
    CGFloat barHeight = (f.size.height - f.size.width) / 2;
    UIGraphicsBeginImageContext(f.size);
    [[UIColor colorWithWhite:0 alpha:.5] set];
    UIRectFillUsingBlendMode(CGRectMake(0, 0, f.size.width, barHeight), kCGBlendModeNormal);
    UIRectFillUsingBlendMode(CGRectMake(0, f.size.height - barHeight, f.size.width, barHeight), kCGBlendModeNormal);
    UIImage *overlayImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    UIImageView *overlayIV = [[UIImageView alloc] initWithFrame:f];
    overlayIV.image = overlayImage;
    [imagePickerController.cameraOverlayView addSubview:overlayIV];
}

imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];

Then, after you get a picture back from the UIImagePickerController, crop it to a square with something like this:

//Crop the image to a square
CGSize imageSize = image.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
if (width != height) {
    CGFloat newDimension = MIN(width, height);
    CGFloat widthOffset = (width - newDimension) / 2;
    CGFloat heightOffset = (height - newDimension) / 2;
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(newDimension, newDimension), NO, 0.);
    [image drawAtPoint:CGPointMake(-widthOffset, -heightOffset)
                   blendMode:kCGBlendModeCopy
                       alpha:1.];
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}

And you're done.



回答2:

@Anders answer was very close to correct for me on iPhone 5. I made the following modification to add an overlay hardcoded for iPhone 5:

CGRect f = imagePickerController.view.bounds;
f.size.height -= imagePickerController.navigationBar.bounds.size.height;
UIGraphicsBeginImageContext(f.size);
[[UIColor colorWithWhite:0 alpha:.5] set];
UIRectFillUsingBlendMode(CGRectMake(0, 0, f.size.width, 124.0), kCGBlendModeNormal);
UIRectFillUsingBlendMode(CGRectMake(0, 444, f.size.width, 52), kCGBlendModeNormal);
UIImage *overlayImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

UIImageView *overlayIV = [[UIImageView alloc] initWithFrame:f];
overlayIV.image = overlayImage;
overlayIV.alpha = 0.7f;
[imagePickerController setCameraOverlayView:overlayIV];`

I hope this helps someone.