Exploring iPhone Graphics Part 1
April 9th, 2008 Posted in Software Development, iPhone![]()
The series of articles is going to discuss creating graphics on the iPhone using the SDK. Part 1 will start out with the basics by drawing some simple 2D graphics. In later articles I plan to get into animation, using the accelerometers and maybe even a little OpenGL.
The sample application for this article is very simple. It is just a Cocoa Touch application with a single view. The view’s drawRect method contains all of the code. Again, this first article is very introductory.
All drawing is done directly onto a graphics context. For this example we are drawing on the current UI graphics context. You can also create your own graphics context and draw into it but this article won’t be getting into that process.
The first step is to get the graphics context and clear it. Technically since we are only really rendering this scene once and nothing is changing I don’t need to clear it but I will anyway.
1 2 3 4 5 | - (void)drawRect:(CGRect)rect { // Get the graphics context and clear it CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextClearRect(ctx, rect); |
The UIGraphicsGetCurrentContext function returns the current graphics context for this UIView object. The CGContextRef value returned from this call is only valid until the drawRect method returns. You should not try to save the value in a variable and use it later.
CGContextClearRect does just what it says. It clears a rectangle. It actually makes the entire rectangle black. I haven’t found a way to clear to a different color.
The first object we are going to draw is a solid square colored red.
1 2 3 | // Draw a red solid square CGContextSetRGBFillColor(ctx, 255, 0, 0, 1); CGContextFillRect(ctx, CGRectMake(10, 10, 50, 50)); |
The CGContextSetRGBFillColor function is used to set the current fill color for the context. You give it values for red, green, blue and alpha. There are other ways to set the fill color but this is the easiest I’ve found. We’ll talk about the alpha value later.
You pass CGContextFillRect a rectangle created with CGRectMake and it will draw your rectangle using the current fill color. Nothing to it. Very simple stuff.
This code creates a solid circle colored green.
1 2 3 | // Draw a green solid circle CGContextSetRGBFillColor(ctx, 0, 255, 0, 1); CGContextFillEllipseInRect(ctx, CGRectMake(100, 100, 25, 25)); |
Again we use CGContextSetRBGFillColor to set the current fill color. CGContextFillEllipseInRect is passed a rectangle and will draw an ellipse within the bounds of the rectangle. We are giving it a square so our ellipse will end up being a circle.
The following code will draw the outline of a circle in blue:
1 2 3 | // Draw a blue hollow circle CGContextSetRGBStrokeColor(ctx, 0, 0, 255, 1); CGContextStrokeEllipseInRect(ctx, CGRectMake(200, 200, 50, 50)); |
This time we use CGContextSetRGBStrokeColor instead of CGContextSetRGBFillColor. The current stroke color is the color used to draw stroke type graphics. CGContextStrokeEllipseInRect is just like CGContextFillEllipseInRect except it draws a hollow circle instead of a filled circle.
This code draws the outline of square in yellow.
1 2 3 | // Draw a yellow hollow rectangle CGContextSetRGBStrokeColor(ctx, 255, 255, 0, 1); CGContextStrokeRect(ctx, CGRectMake(195, 195, 60, 60)); |
This code constructs a triangle from a set of three lines.
1 2 3 4 5 6 | // Draw a purple triangle with using lines CGContextSetRGBStrokeColor(ctx, 255, 0, 255, 1); CGPoint points[6] = { CGPointMake(100, 200), CGPointMake(150, 250), CGPointMake(150, 250), CGPointMake(50, 250), CGPointMake(50, 250), CGPointMake(100, 200) }; CGContextStrokeLineSegments(ctx, points, 6); |
The CGContextStrokeLineSegments function is passed an array of points and will draw lines between each pair of points.
The following code will draw the text string “TrailsintheSand.com”:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Draw the text TrailsintheSand.com in light blue char* text = "TrailsintheSand.com"; CGContextSelectFont(ctx, "Helvetica", 24.0, kCGEncodingMacRoman); CGContextSetTextDrawingMode(ctx, kCGTextFill); CGContextSetRGBFillColor(ctx, 0, 255, 255, 1); CGAffineTransform xform = CGAffineTransformMake( 1.0, 0.0, 0.0, -1.0, 0.0, 0.0); CGContextSetTextMatrix(ctx, xform); CGContextShowTextAtPoint(ctx, 10, 300, text, strlen(text)); |
When drawing text we need a font. In this case we are selecting a 24 point Helvetica font into the current context with the CGContextSelectFont function.
CGContextSetTextDrawingMode is used to set how the text will be drawn. In this case it is set to kCGTextFill which means the text will be filled with the current fill color. You can draw the text outlined using kCGTextStroke or both filled and outlined with kCGTextFillStroke.
Since we are using kCGTextFill we need to set a fill color.
CGContextShowTextAtPoint draws the text at the specified x,y coordinate within the view. Notice that it takes a C style null terminated string.
You’ll notice that I skipped the call to CGAffineTransformMake function call. If you run this code without it your text will be drawn up-side down but in the correct position on the screen. The CGAffineTransformMake function creates a transformation matrix and the CGContextSetTextMatrix will cause this matrix to be applied to all text drawn on the context. The matrix above will cause to text to be flipped so it is right-side up. It seems strange to me that the default would be upside down. Apparently fonts are stored with a different coordinate system. You can also use transformation matricies to do things like rotate and scale your text.
Now we are going to draw a filled gray transparent rectangle over some of the other graphics that we’ve already drawn.
1 2 3 | // Draw a transparent filled circle over other objects CGContextSetRGBFillColor(ctx, 200, 200, 200, 0.5); CGContextFillEllipseInRect(ctx, CGRectMake(100, 200, 150, 150)); |
The last parameter passed to CGContextSetRGBFillColor is the alpha value and controls the transparency of what is drawn. This value ranges from 0 to 1 with 0 being completely transparent and 1 being completely opaque.
The last graphics example is drawing an image.
1 2 3 4 5 6 7 8 9 10 | // Load image from applicaiton bundle NSString* imageFileName = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"iphone_sdk.png"]; CGDataProviderRef provider = CGDataProviderCreateWithFilename([imageFileName UTF8String]); CGImageRef image = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault); CGDataProviderRelease(provider); // Draw image CGContextDrawImage(ctx, CGRectMake(200, 0, 100, 100), image); CGImageRelease(image); } |
The image we are going to draw has been added as a resouce to the project (just like a source file) and will be compiled into the application bundle. We get a reference to the bundle by calling the mainBundle: method of NSBundle. Then we get the resourcePath by calling the resourcePath: method on the mainBundle. This returns an NSString object that we call stringByAppendingPathComponent: on passing it the file name to get the full path to the file name.
Now that we have the file name we create a CGDataProviderRef object using the CGDataProviderCreateWithFilename function.
Now we can get the actual CGImageRef object that we’ll use to draw the image. The CGImageCreateWithPNGDataProvider function takes our provider and turns it into an image.
We are done with the provider so we call CGDataProviderRelease to release its memory and resources.
Finally we can call the CGContextDrawImage function to actually draw the image on the graphics context. We pass it a rectangle that the image will be drawn into. The image will be automatically resized to fit the rectangle with no regard to the image aspect ratio.
Lastly we use CGImageRelease to free up the image.
The only problem with this code is that the image will be drawn up-side down. I assume this is the same reason fonts default to being drawn up-side down. I’ll talk about how to correct this in the next article.
Screenshot:

The next article in this series will go into more detail on drawing images.












Related Articles:
Thanks for the tutorials Pete — keep up the great work!
Thank you very much! I appreciate your tutorials.
Nice post…
Could you give me a quick primer on how to draw a sinus curve (or similar curve) with the data coming from an array?
All your examples are simple geometric shapes…
I am new to graphics.
I just posted an new article showing how to plot a sin wave with the iPhone SDK.
http://trailsinthesand.com/plotting-a-sine-wave-with-the-iphone-sdk/
[...] the following request from Leo on the Exploring iPhone Graphics Part 1 article: Could you give me a quick primer on how to draw a sinus curve (or similar curve) with the [...]
Thanks! I think the message from your tutorial is that the graphics libraries for the iPhone are powerful and easy to handle.
Hi Pete,
You seem to know the iPhone well. How about a tidbit on File I/O? This is a basic exercise in any OS/language…
Great site!
Leo
Hi,
Fantastic Tutorial. Indeed! I’m trying to grab the yahoo finance charts on i-phone - will you please throw some light on that aspect.
Thanx again.
Pete,
How do you get these graphic routines to work OUTSIDE the method you show?
- (void)drawRect:(CGRect)rect{
}
I ask this because it seems as if this method is a ONCE only one.
My goal is to draw a curve (similar to the sinus one) with data I have in an array, but slowly - ie. each dot is drawn with a timer - sort of like an oscilloscope tracing.
Can you help me on how to draw your examples in “oscilloscope” mode where I can draw them at whatever speed I decide on with a timer?
Thanks in advance.
I’ll be posting a simple animation sample soon that might help you.
Thanks Pete - I will be tuned in!
[...] Part 1 of this series of articles we drew some simple graphic primitives on the iPhone display. In this [...]
I’m trying to figure out how to fill text with a gradient (like the numbers in the Calendar app have a subtle gradient). I haven’t found any examples of how to do this. Could subclassing UILabel accomplish this? How could I do this with an existing Label built in Interface Builder?
I’m betting you already know how to do this. Thanks.
Thanks for the examples, they’ve helped me a lot.
However, the color setting calls (like CGContextSetRGBStrokeColor) are a little misleading in the examples. With values like 0 and 255 it would appear that they are single byte values when they are actually supposed to be floats in the range of 0 to 1. Anything greater than 1 is treated as full intensity.
Is there any way to have the source code of this article? I am a beginner and I think something is missing on my app. The drawRect method is never executed.
Hi very nice tutorial you have given can you tell me how can i rotates,scale and translate an image. I will be really great of you.Please anyone who have answer please let me know
Excellent iphone graphics tutorial. Thanks.
Can any one please tell me how to draw Pie-graph ?
Is there way to draw the circle, filled with diff colors
similar to pie chart?
Hi,
with iPhone 2.0 this method is not working …
what is its alternative ….
how to draw a rectangle
Thanks for this tutorial! I’ve been struggling with fonts for a while now. Turns out my problem was that I was trying to select a font that couldn’t be selected. (”Arial”)
Anyways, is there a list of which fonts are available and what’s the strings to use to refer to them?
hi…………….
[...] This link has a bit of code for drawing text Exploring iPhone Graphics Part 1 | Trails in the Sand [...]
CGContextSetRGBFillColor takes colour % float of 0.0-1.0, much the same as transparency, rather than the 0-255 RGB values.
So you need to call it like:
CGContextSetRGBFillColor(context, 1.0, 0.5058, 0.04, 1.0);
Which would net you a dark orange colour.
Great stuff.
Can you give us a hint about how to build this project in Xcode? I’m not sure if I should be doing a view-based, OpenGL-based, or other type of app. Do you have an .xcodeproj file you can share for this? Thanks for putting up the tutorial!
Thank you..
This code is very helpful to me to solve my CGContextRef object reloading..
I need very good help to develop game..and I m new to this gamming world..
I need help to develop game with 3d graphics and best animation effect in iphon game..any one there?
[...] Exploring iPhone Graphics Part 1 [...]
There is mistake in your code.
RGB color components are float and set from 0 to 1.
Your code:
CGContextSetRGBFillColor(ctx, 0, 255, 255, 1);
is similar to:
CGContextSetRGBFillColor(ctx, 0, 1, 1, 1);
Hi,
I’m just getting into developing for the Ipod, these tutorials are just what I need to get me on the right track. Thanks.
You never did explain the upside-down image in your other articles. How do you fix that?
Hi, great tutorial, I had to add the Core Graphics framework though which seamed odd, I thought it was built into the standard framework?!
One question, how do we not have the black background when drawing in the context? Seams very limiting, there must be a way to draw without it or else circles and ellipses on while backgrounds can never be used!! Any ideas?
ah in answer to my own question
We can set the opaque property of the view we are drawing in to “NO” to not have a background..
or changing the backgroundColor property will change the background to that color.
hope that helps some…
Great tutorial. Where can I get the source to compile? (Simple as it may be) like in part 2?
Hi
I have one doubt….. how can I erase only the part of an image where I touched…. let me make it clear
I have an image in my view and when i touch anywhere in that image… I want that part only to be removed….how can I do it??
-John
Help!
How do i use it in xcode? which type of project should i create? and where should i put the code you’ve provided?
Please help me !
i make an app like a slide show with back, previous button to change Image one by one. But when i using large image it crash. Now i,m using 64 jpg pics , size~20kb/1pic.
help me or i die
! (U can add nick hoangtuanfithou, please)
code like that :
//Init Image Array
-(void)InitImageArray1
{
myAnimationImages1 = [[NSMutableArray alloc] init];
for ( int i = 0; i < 24; i++ )
{
NSAutoreleasePool *poolArray=[[NSAutoreleasePool alloc] init];
NSString *fileName = [NSString stringWithFormat:@"001 (%d)",i];
image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName ofType:@”jpg”]];
[myAnimationImages1 addObject:image];
[poolArray release];
}
}
//Change Image
self.mainImage.image = [self.myAnimationImages1 objectAtIndex:animationImageArrIndex];
[...] Exploring iPhone Graphics Part 1 – Basic shapes tutorial repeated all over the place, this is the best one that I’ve seen. Exploring iPhone Graphics Part 2 – Very good beginners animation tutorial with Core Graphics. [...]
Very nice tutorial !!!
Allen
[...] Exploring iPhone Graphics Part 1 [...]
Hi,
I’m trying to draw a gauge — like a speedometer or volt meter.
Do you know of any links that point to source code that I can use as a starting point.
Thanks,
MM.
hi..somebody
how can i draw a graph in iPhone App
pls HELP ME..!
Damn I’m getting so mad, that nothing happens if I draw.
1: I make a view based app
2: Go to the View controller .m file
3: Do the DrawRect method
- (void)drawRect:(CGRect)rect
{
// Get the graphics context and clear it
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextClearRect(ctx, rect);
// Draw a red solid square
CGContextSetRGBFillColor(ctx, 1.0, 0.0, 0.0, 1.0);
CGContextFillRect(ctx, CGRectMake(10, 10, 50, 50));
}
And nothing happens. I’ve wasted my whole day. Any help?
Should I redraw something? Why doest it draws on my template mede view??? thx
maybe there have to be some trick, since you made a Cocoa Touch app from the start?