Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 02-26-2010, 12:00 AM   #1 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 99
hobbyCoder is on a distinguished road
Default The imagePickerController hates me, eats my photos

I have a magic trick app that's been on the store since 2008 but still doesn't work reliably, and I feel horrible about it. The app takes a picture as part of the trick, but if device memory is low / fragmented / or the stars are aligned improperly, it often just sort of drops the picture. The unfortunate user is halfway through a magic trick when, after taking his pic, he sees not the image he just shot, but the application's home screen. I have tried to debug this myself on and off but I'm just not equal to the task (I'm definitely in the "hobbyist" category, like my nick implies).

My current, unreleased version of the app uses a simple .png file as a camera overlay to make performing part of the trick easier, but it didn't make the dreaded lost photo bug any better or worse. I have long assumed that resizing the raw photo to just 360x480 (that's as close as you can get to screen resolution without changing the aspect ratio or cropping the photo down) would reduce my RAM needs and eliminate the bug, but I've got that implemented in the below code and it didn't make the problem better or worse either.

Any obvious thoughts from looking at these methods guys?

Code:
- (IBAction)takePhoto {
	if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
	{
		
		// code for using overlay and an NSTimer to get rid of it from http://stackoverflow.com/questions/2081872/camera-overlay-view-just-for-preview
		UIImagePickerController *anImagePickerController = [UIImagePickerController new];
		anImagePickerController.delegate = self;
		anImagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
		
		outline.hidden = YES;
		anImagePickerController.cameraOverlayView = outline;
		
		[self presentModalViewController:anImagePickerController animated:NO];
		[anImagePickerController release];	
		
		[NSTimer scheduledTimerWithTimeInterval:0.1
										 target:self
									   selector:@selector(timerFireMethod:)
									   userInfo:outline
										repeats:YES];
		
	}
}

// this method is also taken from the stackoverflow discussion web

- (void)timerFireMethod:(NSTimer*)theTimer {
    UIView *cameraOverlayView = (UIView *)theTimer.userInfo;
    UIView *previewView = cameraOverlayView.superview.superview;
	
    if (previewView != nil) {
        [cameraOverlayView removeFromSuperview];
        [previewView insertSubview:cameraOverlayView atIndex:1];
		
        cameraOverlayView.hidden = NO;
		
        [theTimer invalidate];
    }
}

- (void)imagePickerController:(UIImagePickerController *)picker
		didFinishPickingImage:(UIImage *)image
				  editingInfo:(NSDictionary *)editingInfo {
	[self useImage:image];
	[[picker parentViewController] dismissModalViewControllerAnimated:YES];
	[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];

}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
	[[picker parentViewController] dismissModalViewControllerAnimated:YES];
}

- (void)useImage:(UIImage *)theImage { // resize raw iPhone photo to screen res to try and save some memory
	CGSize screenSize = {360,480};
	UIGraphicsBeginImageContext( screenSize );// a CGSize that has the size you want
	[theImage drawInRect:CGRectMake(0,0,screenSize.width,screenSize.height)];
	//image is the original UIImage
	UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	[theImage release];
	
	userPhoto.image = newImage; // userPhoto is UIImageView that displays the photo after the camera interface is dismissed
}


- (void)didReceiveMemoryWarning {
	[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
	// Release anything that's not essential, such as cached data
}


- (void)dealloc {
	[cardView release];
	[super dealloc];
}
hobbyCoder is offline   Reply With Quote
Old 02-26-2010, 01:02 AM   #2 (permalink)
Registered Member
 
Join Date: Sep 2008
Location: Denver
Posts: 172
BSDimwit is on a distinguished road
Default try this...

I'm not sure if this is what you need without seeing more code.... but you aren't retaining the image anywhere... try this..

but also post your your viewDidLoad, and viewDidUnload methods for the viewController class that these methods are a part of. It might be that the picker is burning too much memory, so your hidden view (the view the picker is hiding) might be unloading unexpectedly (while its hidden by the picker), and when it reloads right before it is shown once the picker view is dismissed, it might be doing some property initialization that you aren't expecting... I would put a few NSLog statements in your viewDidLoad and unload methods to see if they are getting fired when you aren't expect it.

Can I have my Hundred Dollars now

Code:
- (void)useImage:(UIImage *)theImage { // resize raw iPhone photo to screen res to try and save some memory
        UIImage *myRawImage = [theImage retain];
	CGSize screenSize = {360,480};
	UIGraphicsBeginImageContext( screenSize );// a CGSize that has the size you want
	[myRawImage drawInRect:CGRectMake(0,0,screenSize.width,screenSize.height)];
	//image is the original UIImage
	UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	[myRawImage release];
	
	userPhoto.image = newImage; // userPhoto is UIImageView that displays the photo after the camera interface is dismissed
}

Last edited by BSDimwit; 02-26-2010 at 01:28 AM. Reason: forgot the explanation.
BSDimwit is offline   Reply With Quote
Old 02-26-2010, 01:25 AM   #3 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 99
hobbyCoder is on a distinguished road
Default

Quote:
Originally Posted by BSDimwit View Post
You aren't retaining the image sent to the delegate method. That image is an autorelease object and when you dismiss the view, it gets dropped from the view stack..., it releases and poof, your image is gone... by retaining it, you give your delegate method time to actually do the image resize before the image is ripped out from under it by the autorelease. Of course, because you retain it, you must release it when you are done using it.

Can I have my Hundred Dollars now
I want to have your babies! That actually makes some kind of sense, even to my reptilian sized brain. As soon as I un-break my code from some unrelated but badly needed UI changes, I'll confirm it's working so that your full glory can be known to all. I see you haven't forgotten about my original thinking of a bounty... lol... I'm happy to oblige, private message me your email address and I'll paypal you after I'm sure the bug is good and truly dead. It's worth that much 2x over because this bug has been driving my poor magician customers crazy, and this is the more profitable of my two apps (though that's not saying much - heh).
hobbyCoder is offline   Reply With Quote
Old 02-26-2010, 01:29 AM   #4 (permalink)
Registered Member
 
Join Date: Sep 2008
Location: Denver
Posts: 172
BSDimwit is on a distinguished road
Default reread my post, I saw a few things I might have missed

subject says it all.... And ignore my line about the bounty... I was kidding. This site has helped me a bunch of times for free so its nice to return the favor when I can. I also have recently been playing the same methods... doing almost exactly the same sort of thing in fact so I was just at the right place at the right time... which is why I am telling you to check your viewDidLoad and unload methods. It might be that if you are initing a few image properties in viewDidLoad, you might want to move those to an awakeFromNib method so that your inits aren't redone by a load and unload, then subsequent reload of the view.

Todd

Last edited by BSDimwit; 02-26-2010 at 01:35 AM.
BSDimwit is offline   Reply With Quote
Old 02-26-2010, 01:56 AM   #5 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 99
hobbyCoder is on a distinguished road
Default

Quote:
Originally Posted by BSDimwit View Post
This site has helped me a bunch of times for free so its nice to return the favor when I can.
That puny little dealloc method is as close as I've got to a viewDidUnload
Code:
- (void)dealloc {
	[cardView release];
	[super dealloc];
}
That's because this code is much older than iPhone OS 3.0. I got so frustrated over some bugs that I couldn't squash that I went into retirement for a year, feeling I was out of my league trying to write apps for the store. Now I've taken a couple Java classes, and still have no clue--- BUT, when I re-read iPhone programming tutorials I actually understand a fair bit. I think I'm six months from marginal competence at long last! lol

Should I write a viewDidUnload method? This app will rely heavily on the image overlay in the camera, so it's going to be 3.1+ only once the update is released.

Thanks for this help Todd, of course this morally obligates me to come back later when I'm less clueless and help some other poor sap.

The viewDidLoad method is a bit confusing because it displays a false home screen for the trick (complete with nifty calendar that shows the real date). The method displays my fake screen that can do absolutely nothing except use its working "camera" button, that triggers the takePhoto method (the spectator doesn't realize an app is running when the camera icon is pressed). You could easily be right about this just being related to my failure to retain the image, I'll test the code extensively in a couple hours when I get the app back in workable condition... Anyhow, here's viewDidLoad, for completeness but it's probably not helpful:

Code:
- (void)viewDidLoad {
	[super viewDidLoad];
	
	// Configure and start the accelerometer
    [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)];
    [[UIAccelerometer sharedAccelerometer] setDelegate:self];
	
	photoTaken = FALSE;

	NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
	
	[dateFormatter setDateFormat:@"dd"];
	int day = [[dateFormatter stringFromDate:[NSDate date]] intValue];

	NSCalendar *gregorian = [[NSCalendar alloc]
							 initWithCalendarIdentifier:NSGregorianCalendar];
	NSDate *date = [NSDate date];
	NSDateComponents *weekdayComponents =
    [gregorian components:NSWeekdayCalendarUnit fromDate:date];
	int weekday = [weekdayComponents weekday];
	if (weekday == 1) {
			dayOfWeek.text = [NSString stringWithFormat:@"Sunday"];
	}
	if (weekday == 2) {
		dayOfWeek.text = [NSString stringWithFormat:@"Monday"];
	}
	if (weekday == 3) {
		dayOfWeek.text = [NSString stringWithFormat:@"Tuesday"];
	}
	if (weekday == 4) {
		dayOfWeek.text = [NSString stringWithFormat:@"Wednesday"];
	}
	if (weekday == 5) {
		dayOfWeek.text = [NSString stringWithFormat:@"Thursday"];
	}
	if (weekday == 6) {
		dayOfWeek.text = [NSString stringWithFormat:@"Friday"];
	}
	if (weekday == 7) {
		dayOfWeek.text = [NSString stringWithFormat:@"Saturday"];
	}
	dateOfMonth.text = [NSString stringWithFormat:@"%d", day];
	[dateFormatter release];	
	[gregorian release];
}
Maybe best to let me wrestle with implementing your thoughts so far, and I'll report back on where I stand tomorrow. I'll also try sprinkling some NSLog statements around and see if it helps me get a clue.
hobbyCoder is offline   Reply With Quote
Old 02-26-2010, 01:55 PM   #6 (permalink)
Registered Member
 
Join Date: Sep 2008
Location: Denver
Posts: 172
BSDimwit is on a distinguished road
Default Don't see any either

Hi Again,

Yeah, your viewDidLoad doesn't have any of the things I was worried about so see how retaining that UIImage works for you.

I will look over your code and overlay generation methods a bit more to see if I can't find anything else that gives me pause.

Todd
BSDimwit is offline   Reply With Quote
Old 02-26-2010, 03:59 PM   #7 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 99
hobbyCoder is on a distinguished road
Default

Quote:
Originally Posted by BSDimwit View Post
Hi Again,

Yeah, your viewDidLoad doesn't have any of the things I was worried about so see how retaining that UIImage works for you.

I will look over your code and overlay generation methods a bit more to see if I can't find anything else that gives me pause.

Todd

Sadly, the bug still lives, though it seems to take a more badly RAM deprived iPhone to make it misbehave now (but it's hard to be certain). I will be adding NSLog statements this evening and try to understand my own code better before I look to the next steps. 'tis truly a nasty bug.
hobbyCoder is offline   Reply With Quote
Old 02-26-2010, 04:03 PM   #8 (permalink)
Registered Member
 
Join Date: Sep 2008
Location: Denver
Posts: 172
BSDimwit is on a distinguished road
Default

Quote:
Originally Posted by hobbyCoder View Post
Sadly, the bug still lives, though it seems to take a more badly RAM deprived iPhone to make it misbehave now (but it's hard to be certain). I will be adding NSLog statements this evening and try to understand my own code better before I look to the next steps. 'tis truly a nasty bug.
If you want to shoot me a copy of your project, I would be happy to look at it further... I've been using an overlay view in one of my apps (camera app) and it doesn't suffer from the same thing as yours. Of course I promise to do nothing nefarious with your code and will keep it in the strictest confidence, but I can certainly understand if you hesitate to do that.

Todd
BSDimwit is offline   Reply With Quote
Old 02-26-2010, 04:50 PM   #9 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 99
hobbyCoder is on a distinguished road
Default I sent you a private message

Quote:
Originally Posted by BSDimwit View Post
If you want to shoot me a copy of your project, I would be happy to look at it further... I've been using an overlay view in one of my apps (camera app) and it doesn't suffer from the same thing as yours. Of course I promise to do nothing nefarious with your code and will keep it in the strictest confidence, but I can certainly understand if you hesitate to do that.

Todd
Thanks for everything you've done.
hobbyCoder is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 345
9 members and 336 guests
2Apps1Day, akacaj, c2matrix, esoteric, givensur, mjnafjke, Pudding, SLIC, Techgirl-52
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,650
Threads: 94,115
Posts: 402,887
Top Poster: BrianSlick (7,990)
Welcome to our newest member, soohyun
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 10:10 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0