Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crop automatically using camera like instagram

Tags:

ios

image

crop

I want to take an square picture from the app like instagram. However I don't know how to do it. I know that the y, the image still has to be cropped, and the camera is capturing the whole image all the time, it's only I am cropping it "live" in the view. When the image is captured, it is still the whole image and still has to be cropped. Only the user doesn't see it happening as it's all done in the background. Once you capture the image with your devices camera, put it to an instance of a UIImage then write a method that will take that UIIMage and use a CGRefImageContext to resize it then either overwrite your original UIImage instance if no longer need the original. I don't get how to do this. Is there a site that shows how to do this? or is there a easier way to do it.

like image 631
user2590480 Avatar asked Dec 25 '22 23:12

user2590480


1 Answers

First, you need to take the photo with the camera, so add this code where you want to take the picture.

UIImagePickerController *pickerController = [[UIImagePickerController alloc] init];

if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
    pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
    pickerController.delegate = self;
    [self presentViewController:pickerController 
                       animated:YES
                     completion:nil];
}

Then, you need to implement delegate methods. Your class must conform to UIImagePickerControllerDelegate, documented here. In the imagePickerController: didFinishPickingMediaWithInfo: method, you can take the taken photo in a UIImage with:

UIImage *imageTaked = info[UIImagePickerControllerOriginalImage]; 

If you want, at this point you can take the metadata of the taken photo with

info [UIImagePickerControllerMediaMetadata];

Finally, when you have your photo in a UIImage, you can crop the image as follows:

CGFloat x, y, side; //We will see how to calculate those values later.
UIImage* imageCropped;
CGRect cropRect = CGRectMake(x,y,side,side);
CGImageRef imageRef = CGImageCreateWithImageInRect([imageTaked CGImage], cropRect);
imageCropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);

So, the important thing here is how to calculate the cropRect to cut the centre square of the UIImage. To do that, you can calculate x, y and side as follows:

side = MIN(imageTaked.size.width, imageTaked.size.height
x = imageTaked.size.width / 2 - side / 2;
y = imageTaked.size.height / 2 - side / 2;

Ok, so, to summarise, all the code inside the imagePickerController: didFinishPickingMediaWithInfo: method results in:

- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *imageTaked = info[UIImagePickerControllerOriginalImage]; 
    //You can take the metadata here => info [UIImagePickerControllerMediaMetadata];

    UIImage* imageCropped;

    CGFloat side = MIN(imageTaked.size.width, imageTaked.size.height);
    CGFloat x = imageTaked.size.width / 2 - side / 2;
    CGFloat y = imageTaked.size.height / 2 - side / 2;

    CGRect cropRect = CGRectMake(x,y,side,side);
    CGImageRef imageRef = CGImageCreateWithImageInRect([imageTaked CGImage], cropRect);
    imageCropped = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
}

EDIT

If you want to send your photo to another device, probably the photo will be rotated. That's because Apple uses exif metadata for images, but other platforms don't. To solve this problem, just use this method to set appropriate metadata info:

-(UIImage*)getImageWithCorrectFiltersFromOriginalImage:(UIImage *)originalImage
{
    UIImageOrientation orientation = UIImageOrientationUp;
    NSNumber* orientationValue = [originalImage valueForProperty:@"ALAssetPropertyOrientation"];
    if (orientationValue) {
        orientation = [orientationValue intValue];
    }

    ALAssetRepresentation *assetRep = [originalImage defaultRepresentation];
    CGImageRef imageRef = [assetRep fullResolutionImage];
    return [UIImage imageWithCGImage:imageRef scale:[assetRep scale] orientation:orientation];
}

Hope it helps! and let me know if something goes wrong during copy-paste process, it's 2:00AM here, and i'm a zombie man right now!

like image 137
lucaslt89 Avatar answered Jan 09 '23 04:01

lucaslt89