我正在开发一个照片应用程序app.Users有和选择从相机和photolibray选择图片。
照片库运作良好。
但是当我试图从相机拍照时它会崩溃。
崩溃后,它在控制台显示消息“已收到内存警告。级别= 1
收到内存警告。级= 2" 。
我使用下面的代码(开源)通过相机拍照:
#import "OverlayViewController.h"
enum
{
kOneShot, // user wants to take a delayed single shot
kRepeatingShot // user wants to take repeating shots
};
@implementation OverlayViewController
@synthesize delegate, takePictureButton, startStopButton,
cancelButton, timedButton,
tickTimer, cameraTimer,
imagePickerController;
#pragma mark -
#pragma mark OverlayViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
{
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:
[[NSBundle mainBundle] pathForResource:@"tick"
ofType:@"aiff"]],
&tickSound);
self.imagePickerController = [[[UIImagePickerController alloc] init] autorelease];
self.imagePickerController.delegate = self;
}
return self;
}
- (void)viewDidUnload
{
self.takePictureButton = nil;
self.startStopButton = nil;
self.timedButton = nil;
self.cancelButton = nil;
self.cameraTimer = nil;
[super viewDidUnload];
}
- (void)dealloc
{
[takePictureButton release];
[startStopButton release];
[cancelButton release];
[timedButton release];
[imagePickerController release];
AudioServicesDisposeSystemSoundID(tickSound);
[cameraTimer release];
[tickTimer release];
[super dealloc];
}
- (void)setupImagePicker:(UIImagePickerControllerSourceType)sourceType
{
self.imagePickerController.sourceType = sourceType;
if (sourceType == UIImagePickerControllerSourceTypeCamera)
{
// user wants to use the camera interface
//
self.imagePickerController.showsCameraControls = NO;
if ([[self.imagePickerController.cameraOverlayView subviews] count] == 0)
{
CGRect overlayViewFrame = self.imagePickerController.cameraOverlayView.frame;
CGRect newFrame = CGRectMake(0.0,
CGRectGetHeight(overlayViewFrame) -
self.view.frame.size.height - 10.0,
CGRectGetWidth(overlayViewFrame),
self.view.frame.size.height + 10.0);
self.view.frame = newFrame;
[self.imagePickerController.cameraOverlayView addSubview:self.view];
}
}
}
// called when the parent application receives a memory warning
- (void)didReceiveMemoryWarning
{
// we have been warned that memory is getting low, stop all timers
//
[super didReceiveMemoryWarning];
// stop all timers
[self.cameraTimer invalidate];
cameraTimer = nil;
[self.tickTimer invalidate];
tickTimer = nil;
}
// update the UI after an image has been chosen or picture taken
//
- (void)finishAndUpdate
{
[self.delegate didFinishWithCamera]; // tell our delegate we are done with the camera
// restore the state of our overlay toolbar buttons
self.cancelButton.enabled = YES;
self.takePictureButton.enabled = YES;
self.timedButton.enabled = YES;
self.startStopButton.enabled = YES;
self.startStopButton.title = @"Start";
}
#pragma mark -
#pragma mark Camera Actions
- (IBAction)done:(id)sender
{
// dismiss the camera
//
// but not if it's still taking timed pictures
if (![self.cameraTimer isValid])
[self finishAndUpdate];
}
// this will take a timed photo, to be taken 5 seconds from now
//
//- (IBAction)timedTakePhoto:(id)sender
//{
// // these controls can't be used until the photo has been taken
// self.cancelButton.enabled = NO;
// self.takePictureButton.enabled = NO;
// self.timedButton.enabled = NO;
// self.startStopButton.enabled = NO;
//
// if (cameraTimer != nil)
// [cameraTimer invalidate];
// cameraTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
// target:self
// selector:@selector(timedPhotoFire:)
// userInfo:[NSNumber numberWithInt:kOneShot]
// repeats:YES];
//
// // start the timer to sound off a tick every 1 second (sound effect before a timed picture is taken)
// if (tickTimer != nil)
// [tickTimer invalidate];
// tickTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
// target:self
// selector:@selector(tickFire:)
// userInfo:nil
// repeats:YES];
//}
- (IBAction)takePhoto:(id)sender
{
[self.imagePickerController takePicture];
}
- (IBAction)startStop:(id)sender
{
if ([self.cameraTimer isValid])
{
// stop and reset the timer
[self.cameraTimer invalidate];
cameraTimer = nil;
[self finishAndUpdate];
}
else
{
self.startStopButton.title = @"Stop";
self.cancelButton.enabled = NO;
self.timedButton.enabled = NO;
self.takePictureButton.enabled = NO;
cameraTimer = [NSTimer scheduledTimerWithTimeInterval:1.5 // fire every 1.5 seconds
target:self
selector:@selector(timedPhotoFire:)
userInfo:[NSNumber numberWithInt:kRepeatingShot]
repeats:YES];
[cameraTimer fire]; // start taking pictures right away
}
}
#pragma mark -
#pragma mark Timer
// gets called by our repettive timer to take a picture
- (void)timedPhotoFire:(NSTimer *)timer
{
[self.imagePickerController takePicture];
NSInteger cameraAction = [self.cameraTimer.userInfo integerValue];
switch (cameraAction)
{
case kOneShot:
{
// timer fired for a delayed single shot
[self.cameraTimer invalidate];
cameraTimer = nil;
[self.tickTimer invalidate];
tickTimer = nil;
break;
}
case kRepeatingShot:
{
// timer fired for a repeating shot
break;
}
}
}
// gets called by our delayed camera shot timer to play a tick noise
- (void)tickFire:(NSTimer *)timer
{
AudioServicesPlaySystemSound(tickSound);
}
#pragma mark -
#pragma mark UIImagePickerControllerDelegate
// this get called when an image has been chosen from the library or taken from the camera
//
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
// give the taken picture to our delegate
if (self.delegate)
[self.delegate didTakePicture:image];
if (![self.cameraTimer isValid])
[self finishAndUpdate];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self.delegate didFinishWithCamera]; // tell our delegate we are finished with the picker
}
@end
任何人都可以帮我解决这个问题。谢谢。
答案 0 :(得分:0)
这是因为内存问题。试试这个 -
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSAutoreleasePool *thePool = [[NSAutoreleasePool alloc]init];
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
// give the taken picture to our delegate
if (self.delegate)
[self.delegate didTakePicture:image];
if (![self.cameraTimer isValid])
[self finishAndUpdate];
[thePool release];
}
从camaera捕获的图像大小约为8 MB。因此,如果您一次捕获多个图像并且所有图像都在内存中,那么内存问题将开始出现。您可以调整图像大小,然后将图像转换为JPEG格式以减小尺寸。
调整图片大小 -
+ (UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}