How to crop UIImage on oval shape or circle shape?
Asked Answered
C

12

41

Please give ideas for how to crop UIImage on oval shape or circle shape. Please share your ideas.

Color answered 30/6, 2011 at 6:5 Comment(0)
F
111
#import <QuartzCore/QuartzCore.h>

CALayer *imageLayer = YourImageview.layer;
        [imageLayer setCornerRadius:5];
        [imageLayer setBorderWidth:1];
        [imageLayer setMasksToBounds:YES];

by increasing radius it will become more round-able.

As long as the image is a square, you can get a perfect circle by taking half the width as the corner radius:

[imageView.layer setCornerRadius:imageView.frame.size.width/2]; 

You also need to add

[imageView.layer setMasksToBounds:YES];

Swift 4.2

import QuartzCore

var imageLayer: CALayer? = YourImageview.layer
imageLayer?.cornerRadius = 5
imageLayer?.borderWidth = 1
imageLayer?.masksToBounds = true
Fairing answered 30/6, 2011 at 7:46 Comment(4)
You are missing [imageLayer setMasksToBounds:YES]; :)Urban
Yes, You have to use the suggestion by Andres to clip the image to the shape of the ImageViewBant
As long as the image is a square, you can get a perfect circle by taking half the width as the corner radius: [imageView.layer setCornerRadius:imageView.frame.size.width/2]; self.imageView.layer.masksToBounds = YES;Wartow
I want to crop image in circular shape. So that we can see only circular path and other path remains transparent.Edelweiss
R
36

I started looking into this a couple of weeks back. I tried all the suggestions here, none of which worked well. In the great tradition of RTFM I went and read Apple's documentation on Quartz 2D Programming and came up with this. Please try it out and let me know how you go.

The code could be fairly easily altered to crop to an elipse, or any other shape defined by a path.

Make sure you include Quartz 2D in your project.

#include <math.h>

+ (UIImage*)circularScaleAndCropImage:(UIImage*)image frame:(CGRect)frame {
    // This function returns a newImage, based on image, that has been:
    // - scaled to fit in (CGRect) rect
    // - and cropped within a circle of radius: rectWidth/2

    //Create the bitmap graphics context
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(frame.size.width, frame.size.height), NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    //Get the width and heights
    CGFloat imageWidth = image.size.width;
    CGFloat imageHeight = image.size.height;
    CGFloat rectWidth = frame.size.width;
    CGFloat rectHeight = frame.size.height;

    //Calculate the scale factor
    CGFloat scaleFactorX = rectWidth/imageWidth;
    CGFloat scaleFactorY = rectHeight/imageHeight;

    //Calculate the centre of the circle
    CGFloat imageCentreX = rectWidth/2;
    CGFloat imageCentreY = rectHeight/2;

    // Create and CLIP to a CIRCULAR Path
    // (This could be replaced with any closed path if you want a different shaped clip)
    CGFloat radius = rectWidth/2;
    CGContextBeginPath (context);
    CGContextAddArc (context, imageCentreX, imageCentreY, radius, 0, 2*M_PI, 0);
    CGContextClosePath (context);
    CGContextClip (context);

    //Set the SCALE factor for the graphics context
    //All future draw calls will be scaled by this factor
    CGContextScaleCTM (context, scaleFactorX, scaleFactorY);    

    // Draw the IMAGE
    CGRect myRect = CGRectMake(0, 0, imageWidth, imageHeight);
    [image drawInRect:myRect];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

Include the following code in your UIView class replacing "monk2.png" with your own image name.

- (void)drawRect:(CGRect)rect {

    UIImage *originalImage = [UIImage imageNamed:[NSString stringWithFormat:@"monk2.png"]];
    CGFloat oImageWidth = originalImage.size.width;
    CGFloat oImageHeight = originalImage.size.height;
    // Draw the original image at the origin
    CGRect oRect = CGRectMake(0, 0, oImageWidth, oImageHeight);
    [originalImage drawInRect:oRect];

    // Set the newRect to half the size of the original image 
    CGRect newRect = CGRectMake(0, 0, oImageWidth/2, oImageHeight/2);
    UIImage *newImage = [self circularScaleAndCropImage:originalImage frame:newRect];

    CGFloat nImageWidth = newImage.size.width;
    CGFloat nImageHeight = newImage.size.height;

    //Draw the scaled and cropped image
    CGRect thisRect = CGRectMake(oImageWidth+10, 0, nImageWidth, nImageHeight);
    [newImage drawInRect:thisRect];

}
Rile answered 25/2, 2013 at 0:14 Comment(0)
A
13

To have imageView in oval shape is not difficult.

You can do the following

UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:yourImageView.bounds];
CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
maskLayer.path = path.CGPath;
yourImageView.layer.mask = maskLayer;

If the rect passed to bezierPathWithOvalInRect is Square the image will be cropped to circle.

Swift Code

let path = UIBezierPath(ovalIn: yourImageView.bounds)
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
yourImageView.layer.mask = maskLayer
Alger answered 13/1, 2015 at 19:53 Comment(3)
can i use uiview instead of uiimage to make it oval ?Corrigendum
how to crop oval shape image for objective c ?Reprobate
This should be the accepted answer as it actually addresses the oval case (and tersely)Lauritz
F
4

To make a RoundShape Image

Step1: in .h file

@property (strong, nonatomic) IBOutlet UIImageView *songImage;

Step2: in .m file

- (void)viewDidLoad
{
    self.songImage.layer.cornerRadius = self.songImage.frame.size.width / 2;
    self.songImage.clipsToBounds = YES;
    
     //To give the Border and Border color of imageview

   self.songImage.layer.borderWidth = 1.0f;
   self.songImage.layer.borderColor = [UIColor colorWithRed:249/255.0f green:117/255.0f blue:44/255.0f alpha:1.0f].CGColor;

}

OR For Swift

cell.songImage.layer.cornerRadius = cell.songImage.frame.size.width / 2;
cell.songImage.clipsToBounds = true
                        
//To give the Border and Border color of imageview
cell.songImage.layer.borderWidth = 1.0
cell.songImage.layer.borderColor = UIColor(red: 50.0/255, green: 150.0/255, blue: 65.0/255, alpha: 1.0).CGColor
Filmdom answered 8/9, 2014 at 8:2 Comment(0)
S
3

After a long search I found the correct way to circle the image

Download the Support archive file from URL http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

#import "UIImage+RoundedCorner.h"
#import "UIImage+Resize.h"

Following lines used to resize the image and convert in to round with radius

UIImage *mask = [UIImage imageNamed:@"mask.jpg"];

mask = [mask resizedImage:CGSizeMake(47, 47) interpolationQuality:kCGInterpolationHigh ];
mask = [mask roundedCornerImage:23.5 borderSize:1];
Suzy answered 30/5, 2012 at 12:31 Comment(0)
T
3

SWIFT

var vwImage = UIImageView(image: UIImage(named: "Btn_PinIt_Normal.png"))
vwImage.frame = CGRectMake(0, 0, 100, 100)
vwImage.layer.cornerRadius = vwImage.frame.size.width/2
Thermistor answered 20/7, 2015 at 9:0 Comment(0)
I
2

If you only need a perfect circle, changing the shape of the UIImageView could help. Simply add the QuartzCore framework to your project and add these lines of code somewhere in the lifecycle before the imageView is displayed:

#import <QuartzCore/QuartzCore.h>
.
.
.

//to crop your UIImageView to show only a circle
yourImageView.layer.cornerRadius = yourImageView.frame.size.width/2;
yourImageView.clipsToBounds = YES;
Idona answered 6/6, 2014 at 12:39 Comment(1)
This dynamic answer is a far better answer than the chosen one.Phellem
I
0

Check out CGImageCreateWithMask. Create a mask of your oval shape, then apply it to the image.

Infinite answered 30/6, 2011 at 6:12 Comment(1)
how to separate oval shape on my image?please help meColor
P
0

you should refer This ...

// Create the image from a png file
UIImage *image = [UIImage imageNamed:@"prgBinary.jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];

// Get size of current image
CGSize size = [image size];

// Frame location in view to show original image
[imageView setFrame:CGRectMake(0, 0, size.width, size.height)];
[[self view] addSubview:imageView];
[imageView release];    

// Create rectangle that represents a cropped image  
// from the middle of the existing image
CGRect rect = CGRectMake(size.width / 4, size.height / 4 , 
(size.width / 2), (size.height / 2)); //oval logic goes here

// Create bitmap image from original image data,
// using rectangle to specify desired crop area
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef]; 
CGImageRelease(imageRef);

// Create and show the new image from bitmap data
imageView = [[UIImageView alloc] initWithImage:img];
[imageView setFrame:CGRectMake(0, 200, (size.width / 2), (size.height / 2))];
[[self view] addSubview:imageView];
[imageView release];
Punkah answered 30/6, 2011 at 6:24 Comment(3)
yeah you have to make " rect " as an oval... read my comments (" oval logic goes here ")Punkah
(" oval logic goes here ") -this link is not worked. pls help me maulikColor
how to implement,pls help me,i don't have idea about that.. i am new in iphone sdk pls help me.Color
T
0

SWIFT 3 answer comes from @Mohammad Sadiq

let path = UIBezierPath.init(ovalIn: workingImgaeView.bounds)
let maskLayer = CAShapeLayer(layer: layer)
maskLayer.path = path.cgPath
workingImgaeView.layer.mask = maskLayer
Toback answered 17/3, 2017 at 8:55 Comment(0)
G
0

This should work, Try pasting below code in viewDidLoad().

self.myImage.layer.cornerRadius = self.myImage.frame.size.width / 2;
self.myImage.clipsToBounds = YES;
Gaffney answered 30/1, 2019 at 7:32 Comment(0)
B
0

I have ported Chris Nelson's excellent answer to Swift 5.10:

func circularScaleAndCropImage(image:UIImage, frame:CGRect) throws -> UIImage {
    // This function returns a newImage, based on image, that has been:
    // - scaled to fit in (CGRect) rect
    // - and cropped within a circle of radius: rectWidth/2
    
    // Define potential errors to be thrown
    enum FunctionError: Error {
        case nilContext
        case nilImage
    }
    
    //Create the bitmap graphics context
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(frame.size.width, frame.size.height), false, 0.0)
    guard let context = UIGraphicsGetCurrentContext() else { throw FunctionError.nilContext }
    
    //Get the width and heights
    let imageWidth = image.size.width
    let imageHeight = image.size.height
    let rectWidth = frame.size.width
    let rectHeight = frame.size.height
    
    //Calculate the scale factor
    let scaleFactorX = rectWidth/imageWidth
    let scaleFactorY = rectHeight/imageHeight
    
    //Calculate the centre of the circle
    let imageCentreX = rectWidth/2
    let imageCentreY = rectHeight/2
    
    // Create and CLIP to a CIRCULAR Path
    // (This could be replaced with any closed path if you want a different shaped clip)
    let radius = rectWidth/2
    context.beginPath()
    context.addArc(center: CGPoint(x: imageCentreX, y: imageCentreY), radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: false)
    context.closePath()
    context.clip()
    
    //Set the SCALE factor for the graphics context
    //All future draw calls will be scaled by this factor
    context.scaleBy(x: scaleFactorX, y: scaleFactorY)
    
    // Draw the IMAGE
    let myRect:CGRect = CGRectMake(0, 0, imageWidth, imageHeight)
    image.draw(in: myRect)
    
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    guard let newImage else { throw FunctionError.nilImage }
    
    return newImage
}

Note that I haven't modified the logic in any way, just the bare minimum to keep the compiler happy.

Bellarmine answered 11/4, 2024 at 10:5 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.