How to render a radial gradient onto a new UIImage on an iphone

Chris picture Chris · Apr 11, 2011 · Viewed 11.4k times · Source

Just wondering how to render a radial gradient (point > circle) onto a new UIImage (iphone). I saw the following:

http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadings/dq_shadings.html

And it made me think i need to use CGShadingRef or CGGradientRef, and use UIImage's 'imageWithCGImage' constructor to go from the CG* to a UIImage... but i can't figure out how.

Any suggestions greatly appreciated!

Answer

Chris picture Chris · Apr 12, 2011

Ok here's the gist of the working solution, let me know if i missed anything (eg releasing handles / references)

Also posted on my blog: http://splinter.com.au/rendering-a-radial-gradient-on-the-iphone-obj

- (UIImage *)radialGradientImage:(CGSize)size start:(float)start end:(float)end centre:(CGPoint)centre radius:(float)radius {
    // Render a radial background
    // http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadings/dq_shadings.html

    // Initialise
    UIGraphicsBeginImageContextWithOptions(size, YES, 1);

    // Create the gradient's colours
    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat components[8] = { start,start,start, 1.0,  // Start color
        end,end,end, 1.0 }; // End color

    CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef myGradient = CGGradientCreateWithColorComponents (myColorspace, components, locations, num_locations);

    // Normalise the 0-1 ranged inputs to the width of the image
    CGPoint myCentrePoint = CGPointMake(centre.x * size.width, centre.y * size.height);
    float myRadius = MIN(size.width, size.height) * radius;

    // Draw it!
    CGContextDrawRadialGradient (UIGraphicsGetCurrentContext(), myGradient, myCentrePoint,
                                 0, myCentrePoint, myRadius,
                                 kCGGradientDrawsAfterEndLocation);

    // Grab it as an autoreleased image
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    // Clean up
    CGColorSpaceRelease(myColorspace); // Necessary?
    CGGradientRelease(myGradient); // Necessary?
    UIGraphicsEndImageContext(); // Clean up
    return image;
}