2011-07-07 75 views
3

我試圖用iPhone快速拍攝並保存照片,速度很快。問題在於它們不會保存到最後,然後永久存在,或者大約1/2到3/4根本不存儲(Write busy錯誤或-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL)。iPhone相機快速拍攝照片,但在保存時遇到問題

我敢打賭,我只是超載手機的內存,但我想不出有效處理它的方式。標準的iPhone相機應用程序可以很好地處理它 - 以幾乎1張照片/秒的速度拍攝,並且可以毫無問題地保存。

有關如何更好地管理流程/內存的任何想法,以便它可以保存,但仍然快速拍攝?

這是我的一些代碼。每當調用self.readyToTake = YES時,都會調用takePicture

 
- (void)takePicture { 
    self.delegate = self; 
    [super takePicture]; 
    self.readyToTake = NO; 
} 

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 
    self.readyToTake = YES; 
    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; 
    UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 
} 

- (void)image:(UIImage*)image didFinishSavingWithError:(NSError *)error contextInfo:(NSDictionary*)info { 
    if (error) 
    { 
     NSLog([NSString stringWithFormat:@"** ERROR SAVING PHOTO: %@", [error localizedDescription]]); 
    } 
} 

謝謝你的幫忙!


編輯

如果我節約,像480×640之前調整照片至更小的尺寸,我趕緊保存沒有問題。但是,我想要捕獲並保存全尺寸圖像。原生的相機應用似乎處理得很好。

回答

2

你可以這樣做。 即,只有在保存上一張照片後才能拍攝下一張照片。 還介紹自動釋放池進行內存管理。

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; 
    UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 
    [pool drain]; 
} 


- (void)image:(UIImage*)image didFinishSavingWithError:(NSError *)error contextInfo:(NSDictionary*)info { 
    if (error) 
    { 
     NSLog([NSString stringWithFormat:@"** ERROR SAVING PHOTO: %@", [error localizedDescription]]); 
    } 
    self.readyToTake = YES; 
} 
+0

這個問題的一些功能將它們保存到相冊在保存上一張照片後啓用下一張照片是相機不再快速拍攝。大多數照片大約需要3-5秒才能保存。 –

+0

我們可以在某些後臺線程中執行保存功能......但如果需要3-5秒,那麼它可能會導致進程垃圾......這一切都取決於硬件,我猜... – Ilanchezhian

1

我會嘗試以異步方式卸載那些呼叫調度隊列的第一件事:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 
    self.readyToTake = YES; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
     UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; 
     UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 
    }); 
} 

如果您還是有問題,我會考慮AVCaptureSession和朋友。這給你更多的控制和更好的性能。有使用這種方法在開發者門戶大樣本項目:SquareCam

編輯

您也可以嘗試使用AssetsLibrary代替UIImageWriteToSavedPhotosAlbum(這是我們在我們所有的應用程序使用)喜歡的東西:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 
    self.readyToTake = YES; 
    // you probably want to create this once and keep it around as a property 
    // on your controller 
    ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init]; 
    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; 
    [library writeImageToSavedPhotosAlbum:image.CGImageRef orientation:(ALAssetOrientation)image.orientation completionBlock:^(NSURL *assetURL, NSError *error) { 
     // do whatever you need to do when the image is saved 
    }]; 
} 
+0

謝謝,藝術。使用調度隊列可以節省大約2倍於之前的時間,但仍然可以節省1/3左右,其餘的要麼是寫'忙'或' - [NSKeyedUnarchiver initForReadingWithData:]:數據是NULL'。有什麼想法嗎? –

+0

使用'AVCaptureSession'確實可以快速捕捉照片,但是照片使用相同的'UIImageWriteToSavedPhotosAlbum'保存(使用我見過的例子)。他們使用AVCaptureSession可以更快速地保存的原因是圖像只有480x640。如果我將它們調整爲很小,但我想要正常尺寸的照片,則可以使用當前方法快速保存。我感謝您的幫助和任何其他想法! –

+0

實際上,你可以通過AVCaptureSessionPresetPhoto使用'AVCaptureSession'獲得全尺寸的照片 你在做什麼'image:didFinishSavingWithError:' –

1

有,爲了方便您的問題的解決方案在它顯示他們保存1秒間隔照片時自動對用戶水龍頭「暫停」按鈕here is its code它developer.apple.com現場一個最好的例子應用肯定可以幫助你,因爲我可以能夠存儲5張consicutive照片1 /秒的速度

請參閱MyViewController.m頁面並獲得在陣列圖像後,你可以使用另一個隊列

相關問題