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
In this article I introduce you to a tutorial series titled, Some Features of C++ Entities....
C++ is a computer language I want to teach in these tutorials. C++ is a very developed language...
In C++ an array is a set of consecutive objects of the same type, in memory. We see how to crea...
A database is a set of related tables. This is part 1, division 1 of a series I have on databas...
To easy way lean java programming language with a basic concepts which will help to build basic...
How to draw over an image and save it (save only the photo and the drawings)...
How to use lightweight migration in your application...
How to dial a phone number from a UITextField...
How to resize a UIImage in a UIImageView and a UIButton...
How to draw over an image and save it (screen shot)...