22

I have read several posts already. And almost everyone suggest using QuartzCore/QuartzCore.h with layer.cornerRadius

I have tried this method and some more methods.

Well, everything works fine when an image doesn't move.

But in my project I always move my images. If I add corner radius or a shadow the image movement is no longer smooth. And it looks aweful!

That is the way I resize my image:

CGSize newSize = CGSizeMake(200*height/image.size.height, 280);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(nil, newSize.width, newSize.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
CGContextClearRect(context, CGRectMake(0, 0, newSize.width, newSize.height));
CGContextDrawImage(context, CGRectMake(0, 0, newSize.width, newSize.height), image.CGImage);
CGImageRef scaledImage = CGBitmapContextCreateImage(context);
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
UIImage *newImage = [UIImage imageWithCGImage: scaledImage];
CGImageRelease(scaledImage);

I would like to know a good way to resize my image, add shadow, corner radius and still have smooth movement of my image.

7 Answers 7

72
// Get your image somehow
UIImage *image = [UIImage imageNamed:@"image.jpg"];

// Begin a new image that will be the new image with the rounded corners 
// (here with the size of an UIImageView)
 UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, [UIScreen mainScreen].scale);

 // Add a clip before drawing anything, in the shape of an rounded rect
  [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds 
                        cornerRadius:10.0] addClip];
 // Draw your image
[image drawInRect:imageView.bounds];

 // Get the image, here setting the UIImageView image
  imageView.image = UIGraphicsGetImageFromCurrentImageContext();

 // Lets forget about that we were drawing
  UIGraphicsEndImageContext();

Try moving with this code, as far as I can remember I used this a while back that makes an image with rounded corners that you can move around into the targets. But it seemed to scale fine...

7
  • 2
    Great job! Rounded + smooth movement! Thanks a lot!
    – iWheelBuy
    May 12, 2012 at 13:32
  • 1
    Wow - i've looked all over and this is the simplest solution i've found which is still very very performant. I've even used it in a UITableViewCell image without stuttering. Brilliant.
    – PapillonUK
    Aug 22, 2012 at 21:56
  • Hi, thanks for the code. It works great except that on retina screen my pictures get a bad quality. Do you have any clue why? Thanks! Sep 12, 2013 at 10:24
  • 3
    @ArnaudDrizard: Instead of UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0); you can use UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, [UIScreen mainScreen].scale);. This should fix your problem!
    – kleo
    Oct 5, 2013 at 19:23
  • 2
    @kleo You are quite correct, and your suggested edit at stackoverflow.com/review/suggested-edits/3073006 should not have been rejected. I've just implemented the change (actually in a slightly different way, but it achieves the same result). Sorry that you didn't get the 2 rep you deserved.
    – Mark Amery
    Oct 5, 2013 at 20:00
13

Rohan's answer is a great one. If anyone is having any probs refactoring it to work in their projects here is a neat refactor that might hopefully help some newer programmers:

+ (UIImage *)imageWithRoundedCornersSize:(float)cornerRadius usingImage:(UIImage *)original
{    
    UIImageView *imageView = [[UIImageView alloc] initWithImage:original];

    // Begin a new image that will be the new image with the rounded corners
    // (here with the size of an UIImageView)
    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);

    // Add a clip before drawing anything, in the shape of an rounded rect
    [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
                            cornerRadius:cornerRadius] addClip];
    // Draw your image
    [original drawInRect:imageView.bounds];

    // Get the image, here setting the UIImageView image
    imageView.image = UIGraphicsGetImageFromCurrentImageContext();

    // Lets forget about that we were drawing
    UIGraphicsEndImageContext();

    return imageView.image;
}
4
  • I prefer to add this as an instance method on UIImage, but rewriting it was only a matter of seconds. Thanks!
    – manmal
    Oct 1, 2013 at 15:59
  • This is good, but you can avoid the corner radius and make it completely round using bezierPathWithOvalInRect. Jan 21, 2014 at 19:31
  • manmal - do you mean you create a subclass of UIImage and then have an instance method that makes self into a circle? If so, really like that idea :-)
    – Charlie S
    Jan 22, 2014 at 22:12
  • Note that the use of a UIImageView is actually not necessary as all you're doing with it is using it for its bounds. You can easily replace this with CGRect bounds = CGRectMake(0,0,original.size.width,original.size.height);.
    – devios1
    Aug 19, 2014 at 20:39
10

There is more optimized memory version of solution of Charlie Seligman. You do not need use UIImageView for this purpose.

+ (UIImage *)imageWithRoundedCornersSize:(float)cornerRadius usingImage:(UIImage *)original
{
    CGRect frame = CGRectMake(0, 0, original.size.width, original.size.height);

    // Begin a new image that will be the new image with the rounded corners
    // (here with the size of an UIImageView)
    UIGraphicsBeginImageContextWithOptions(original.size, NO, original.scale);

    // Add a clip before drawing anything, in the shape of an rounded rect
    [[UIBezierPath bezierPathWithRoundedRect:frame
                                cornerRadius:cornerRadius] addClip];
    // Draw your image
    [original drawInRect:frame];

    // Get the image, here setting the UIImageView image
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    // Lets forget about that we were drawing
    UIGraphicsEndImageContext();

    return image;
}

You can get the round image by specifying cornerRadius equal increased image size twice (image.size.width * 2).

1
  • 1
    I think it's more correct to use UIGraphicsBeginImageContextWithOptions(original.size, NO, original.scale); no?
    – hyperspasm
    Dec 1, 2014 at 3:42
2

try bellow code after import the file #import in your .m file

  yourImageView.layer.shadowColor=[[UIColor grayColor] CGColor];
  yourImageView.layer.cornerRadius = 8;
  yourImageView.layer.shadowOffset=CGSizeMake(2, 2);
  yourImageView.layer.shadowOpacity=1.0;
  yourImageView.layer.shadowRadius=1.0;

Hope ,this help you....

1

If perfomance is bad when animating the image position, it's probably because it's having to render the image with the corner radius every frame. This is inevitable if behind the image there's not a solid color (the "blending" is different in each frame, and thus has to be calculated). If this is not the case, and you can get the background to be of a solid color, make sure you set the UIView.backgroundColor to something other than clearColor, with an alpha 1.0. Also rasterizing the layer might help you (it will store the a cached version of the rendered layer in memory and use that throughout the animation. But again, won't help if the layer is not opaque).

This is how you do this:

UIView *yourView;
CALayer *yourLayer = yourView.layer;

yourLayer.shouldRasterize = YES;
yourLayer.rasterizationScale = [UIScreen mainScreen].scale;
1

Set rounded corners on an image in Objective-C:

yourImageView.layer.cornerRadius = yourRadius;                                   

yourImageView.clipsToBounds = YES;                                 
0

Yes, it is possible.

Import the QuartzCore (#import ) header and play with the layer property of the UIImageView.

ImageView.layer.cornerRadius = Radius;
ImageView.clipsToBounds = YES;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.