KalyanChakravarthy.net

Thoughts, stories and ideas.

Drawing lines and circles using CoreGraphics

Having to create simple images, which only contain say a circle or a line or a combination of simple primitives, in various resolutions for retina and non-retina displays, for use in my iOS apps, annoys me. I find it a lot easier to do it all in code using CoreGraphics.

Here are some of the steps needed to generate a UIImage* of size (30,30) that contains a circle and a line passing through it

1. Setup the canvas size

All frame sizes returned are usually in points. For creating a UIImage we need it in pixels, which is usually double the point size for retina displays.

:::objectivec
// Get the size
CGSize canvasSize = CGSizeMake(30,30);
CGFloat scale = [UIScreen mainScreen].scale;

// Resize for retina with the scale factor
canvasSize.width *= scale;
canvasSize.height *= scale;

2. Initialize the CGContext and get a reference

:::objectivec
// Create the context
UIGraphicsBeginImageContext(canvasSize);
CGContextRef ctx = UIGraphicsGetCurrentContext();

3. Set Stroke size and Fill colors

:::objectivec
CGContextSetLineWidth(ctx, 5.0 * scale);
CGContextSetStrokeColorWithColor(ctx, baseColor.CGColor);
CGContextSetFillColorWithColor(ctx, [UIColor whiteColor].CGColor);

4. Draw & Fill Circle

:::objectivec
// setup the size
CGRect circleRect = CGRectMake( 0, 0, canvasSize.width, canvasSize.height );
circleRect = CGRectInset(circleRect, 5, 5);

// Fill 
CGContextFillEllipseInRect(ctx, circleRect);
CGContextStrokeEllipseInRect(ctx, circleRect)

5. Draw Line

:::objectivec
CGContextMoveToPoint(ctx, canvasSize.width/2.0, 0);
CGContextAddLineToPoint(ctx, canvasSize.width/2.0, canvasSize.height);
CGContextStrokePath(ctx);

6. Extract the UIImage*

:::objectivec
UIImage *retImage = UIGraphicsGetImageFromCurrentImageContext();

---

Full Source

// Get the size
CGSize canvasSize = CGSizeMake(30,30);
CGFloat scale = [UIScreen mainScreen].scale;

// Resize for retina with the scale factor
canvasSize.width *= scale;
canvasSize.height *= scale;

// Create the context
UIGraphicsBeginImageContext(canvasSize);
CGContextRef ctx = UIGraphicsGetCurrentContext();

// setup drawing attributes
CGContextSetLineWidth(ctx, 5.0 * scale);
CGContextSetStrokeColorWithColor(ctx, baseColor.CGColor);
CGContextSetFillColorWithColor(ctx, [UIColor whiteColor].CGColor);

// setup the circle size
CGRect circleRect = CGRectMake( 0, 0, canvasSize.width, canvasSize.height );
circleRect = CGRectInset(circleRect, 5, 5);

// Draw the Circle
CGContextFillEllipseInRect(ctx, circleRect);
CGContextStrokeEllipseInRect(ctx, circleRect)

// Draw Line
CGContextMoveToPoint(ctx, canvasSize.width/2.0, 0);
CGContextAddLineToPoint(ctx, canvasSize.width/2.0, canvasSize.height);
CGContextStrokePath(ctx);   // This actually draws

// Create Image
UIImage *retImage = UIGraphicsGetImageFromCurrentImageContext();