Iphone Drawing Over An Image Part 1

Jan 19th, 2010 by eh9212

How to draw over an image and save it (screen shot)

Create a new view based application and name it DrawOverImageTutorial. Press ⌘ - N and add a new NSObject - UIView class named DrawView. Open up DrawOverImageTutorialViewController.h and enter this:

@interface DrawOverImageTutorialViewController : UIViewController {

}

- (IBAction)choosePic;

- (IBAction)clear;

- (IBAction)saveDrawing;

@end

Open up the .m file and add this:

#import "DrawOverImageTutorialViewController.h"

#import "DrawView.h"

@implementation DrawOverImageTutorialViewController

/*

// The designated initializer. Override to perform setup that is required before the view is loaded.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {

if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {

// Custom initialization

}

return self;

}

*/

/*

// Implement loadView to create a view hierarchy programmatically, without using a nib.

- (void)loadView {

}

*/

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.

- (void)viewDidLoad {

[superviewDidLoad];

}

- (IBAction)choosePic {

UIImagePickerController *imagePicker = [[UIImagePickerControlleralloc] init];

imagePicker.delegate = self;

imagePicker.allowsImageEditing = NO;

[selfpresentModalViewController:imagePicker animated:YES];

}

- (IBAction)clear {

[self.view cancelDrawing];

}

- (IBAction)saveDrawing {

UIGraphicsBeginImageContext(self.view.bounds.size);

[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];

UIImage *finishedPic = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

UIImageWriteToSavedPhotosAlbum(finishedPic, self, @selector(exitProg:didFinishSavingWithError:contextInfo:), nil);

}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {

[selfdismissModalViewControllerAnimated:YES];

[picker release];

[self.view drawPic:image];

}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {

[selfdismissModalViewControllerAnimated:YES];

[picker release];

}

-(void)exitProg:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {

UIAlertView *alertView = [[UIAlertViewalloc] initWithTitle:@"Success"message:@"Your picture has been saved"delegate:selfcancelButtonTitle:nilotherButtonTitles:@"Ok", nil];

[alertView show];

[alertView release];

}

- (void)didReceiveMemoryWarning {

// Releases the view if it doesn't have a superview.

[superdidReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.

}

- (void)viewDidUnload {

// Release any retained subviews of the main view.

// e.g. self.myOutlet = nil;

}

- (void)dealloc {

[superdealloc];

}

@end

The - (void)save method takes what is in the view and makes it into a picture in your saved photo album.

Open up DrawOverImageTutorialViewController.xib and change the View class to DrawView. Put a UIToolbar at the bottom of the view and put three different UIBarButton's in that say Choose Pic, Clear, and Save. Control drag from each of these buttons to the File's Owner and select the appropriate method. Save the xib file.

Open up DrawView.h and type this in:

@interface DrawView : UIView {

UIImage *myPic;

NSMutableArray *myDrawing;

}

-(void)drawPic:(UIImage *)thisPic;

-(void)cancelDrawing;

@end

Open up DrawView.m and type this in:

#import "DrawView.h"

@implementation DrawView

-(void)drawPic:(UIImage *)thisPic {

myPic = thisPic;

[myPicretain];

[selfsetNeedsDisplay];

}

- (void)drawRect:(CGRect)rect {

float newHeight;

float newWidth;

if (!myDrawing) {

myDrawing = [[NSMutableArrayalloc] initWithCapacity:0];

}

CGContextRef ctx = UIGraphicsGetCurrentContext();

if (myPic != NULL) {

float ratio = myPic.size.height/460;

if (myPic.size.width/320 > ratio) {

ratio = myPic.size.width/320;

}

newHeight = myPic.size.height/ratio;

newWidth = myPic.size.width/ratio;

[myPicdrawInRect:CGRectMake(0,0,newWidth,newHeight)];

}

if ([myDrawingcount] > 0) {

CGContextSetLineWidth(ctx, 5);

for (int i = 0 ; i < [myDrawingcount] ; i++) {

NSArray *thisArray = [myDrawingobjectAtIndex:i];

if ([thisArray count] > 2) {

float thisX = [[thisArray objectAtIndex:0] floatValue];

float thisY = [[thisArray objectAtIndex:1] floatValue];

CGContextBeginPath(ctx);

CGContextMoveToPoint(ctx, thisX, thisY);

for (int j = 2; j < [thisArray count] ; j+=2) {

thisX = [[thisArray objectAtIndex:j] floatValue];

thisY = [[thisArray objectAtIndex:j+1] floatValue];

CGContextAddLineToPoint(ctx, thisX,thisY);

}

CGContextStrokePath(ctx);

}

}

}

}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

[myDrawingaddObject:[[NSMutableArrayalloc] initWithCapacity:4]];

CGPoint curPoint = [[touches anyObject] locationInView:self];

[[myDrawinglastObject] addObject:[NSNumbernumberWithFloat:curPoint.x]];

[[myDrawinglastObject] addObject:[NSNumbernumberWithFloat:curPoint.y]];

}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

CGPoint curPoint = [[touches anyObject] locationInView:self];

[[myDrawinglastObject] addObject:[NSNumbernumberWithFloat:curPoint.x]];

[[myDrawinglastObject] addObject:[NSNumbernumberWithFloat:curPoint.y]];

[selfsetNeedsDisplay];

}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

CGPoint curPoint = [[touches anyObject] locationInView:self];

[[myDrawinglastObject] addObject:[NSNumbernumberWithFloat:curPoint.x]];

[[myDrawinglastObject] addObject:[NSNumbernumberWithFloat:curPoint.y]];

[selfsetNeedsDisplay];

}

-(void)cancelDrawing {

[myDrawingremoveAllObjects];

[selfsetNeedsDisplay];

}

- (void)dealloc {

[superdealloc];

[myPicrelease];

[myDrawingrelease];

}

@end

Every time you touch the screen, the -(void)touchesBegan method makes a point in the myDrawing array and then displays it through the - (void)drawRect method.

I am having a problem with the drawing code in one of my apps. When I try to change the stroke color using the CGContextSetStrokeColorWithColor method, all of the lines that I had previously drawn change to that color. How can I prevent this? If you can help me with source code, that would be great.

The source code can be found here: http://sites.google.com/site/iprogramiphones/bukisatutorials/drawingoveranimage

Part 2 is here: http://www.bukisa.com/articles/275674_iphone-drawing-over-an-image-part-2

What kind of tutorial would you like next? Post your answer as a comment on this page.

Problems with coding? Email me @ edwardhinsa@gmail.com.

Have a dog and an iPod Touch or an iPhone? http://itunes.apple.com/us/app/whos-your-doggy/id332655618?mt=8

Subscribe to my tutorial RSS feed here: feed://sites.google.com/site/iprogramiphones/bukisatutorials/posts.xml

eh9212

Written by eh9212
iPhone Programmer

Rate this Article:

Be the first to rate me.

Add new comment

* You must be logged in order to leave comments, please Sign in or join us.

Comments

Ian Oswald, over a year ago
Report comment

I can’t get this to build, comes up with 46 errors, what is supposed to be after the blank #imports?

Related Content