通过相机拍照导致应用程序崩溃

时间:2011-11-08 12:07:59

标签: iphone objective-c

我正在开发一个照片应用程序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

任何人都可以帮我解决这个问题。谢谢。

1 个答案:

答案 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;
}