GabrielAlva / Cool-iOS-Camera

A fully customisable and modern camera implementation for iOS made with AVFoundation.
1.3k stars 152 forks source link

Capture to square #18

Closed ghost closed 9 years ago

ghost commented 9 years ago

Hi guys,

can you help me? I am using your extension. I set cameraView frame to square. But when I capture image I have normal rectangle(full photo). How can I fix it?

Thank you

GabrielAlva commented 9 years ago

Hello, where you implement the delegate function of the camera (didCaptureImage) you can include the following function to crop the resulting image:

UIImage *squareCropImageToSideLength(UIImage *sourceImage,
                                     CGFloat sideLength)
{
    // input size comes from image
    CGSize inputSize = sourceImage.size;

    // round up side length to avoid fractional output size
    sideLength = ceilf(sideLength);

    // output size has sideLength for both dimensions
    CGSize outputSize = CGSizeMake(sideLength, sideLength);

    // calculate scale so that smaller dimension fits sideLength
    CGFloat scale = MAX(sideLength / inputSize.width,
                        sideLength / inputSize.height);

    // scaling the image with this scale results in this output size
    CGSize scaledInputSize = CGSizeMake(inputSize.width * scale,
                                        inputSize.height * scale);

    // determine point in center of "canvas"
    CGPoint center = CGPointMake(outputSize.width/2.0,
                                 outputSize.height/2.0);

    // calculate drawing rect relative to output Size
    CGRect outputRect = CGRectMake(center.x - scaledInputSize.width/2.0,
                                   center.y - scaledInputSize.height/2.0,
                                   scaledInputSize.width,
                                   scaledInputSize.height);

    // begin a new bitmap context, scale 0 takes display scale
    UIGraphicsBeginImageContextWithOptions(outputSize, YES, 0);

    // optional: set the interpolation quality.
    // For this you need to grab the underlying CGContext
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh);

    // draw the source image into the calculated rect
    [sourceImage drawInRect:outputRect];

    // create new image from bitmap context
    UIImage *outImage = UIGraphicsGetImageFromCurrentImageContext();

    // clean up
    UIGraphicsEndImageContext();

    // pass back new image
    return outImage;
}

Now on your didCaptureImage function you can simply crop the image before saving it:

-(void)didCaptureImage:(UIImage *)image
{
    //Crop the image with the squareCropImageToSideLength function
    UIImage *squareImage = squareCropImageToSideLength(image, image.size.width);

    //Save it
    UIImageWriteToSavedPhotosAlbum(squareImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}

This will result in a centered square image based on the width of the original image. Note that if you would like to display the UI to reflect the square image you would need to modify the height of the top bar and create a bottom bar too.