iPhone相机拍摄速度快,但保存照片时存在问题。

3
我正在尝试以iPhone的最快速度拍摄和保存照片。问题在于直到最后才保存,而且需要很长时间,或者有一半到三分之四的照片根本没有保存(“写入繁忙”错误或“-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL”)。
我想我只是过载了手机的内存,但我想不出一种有效处理它的方式。标准的iPhone相机应用程序可以很好地处理这个问题——以几乎每秒1张照片的速度拍摄,并且没有任何问题即时保存。
您对如何更好地管理该进程/内存以便按需保存但仍能快速连续拍摄有什么想法吗?
这里是我的一些代码。每当self.readyToTake = YES时,将调用takePicture。
谢谢您的帮助!
编辑
如果我在保存之前将照片调整为非常小的尺寸,例如480x640,则可以快速保存而没有问题。然而,我想捕捉并保存全尺寸图像。原生相机应用程序似乎可以很好地处理它。
3个回答

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

启用下一张照片保存之后的问题在于相机无法继续快速拍摄。大部分照片需要约3-5秒钟才能保存。 - James Skidmore
我们可以在后台线程中完成保存功能...但是如果需要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
     }];
}

谢谢,Art。使用调度队列可以节省大约2倍的时间,但仍然只能节省约1/3的时间,其余的要么出现“写入繁忙”错误,要么出现“-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL”错误。有什么想法吗? - James Skidmore
使用AVCaptureSession确实可以以快速的速度捕获照片,但是(在我看到的示例中)使用相同的UIImageWriteToSavedPhotosAlbum保存照片。它们使用AVCaptureSession可以更快地保存的原因是图像只有480x640。如果我将它们调整为这么小,则可以使用当前方法同样快速地保存,但我希望能得到正常大小的照片。感谢您的帮助和任何其他想法! - James Skidmore
实际上,您可以使用AVCaptureSessionAVCaptureSessionPresetPhoto从传感器获取全尺寸照片。在image:didFinishSavingWithError:中,您在做什么? - Art Gillespie
另一个尝试的方法是使用AssetsLibrary...请查看我的编辑。 - Art Gillespie

1

在developer.apple.com网站上有一个最佳示例应用程序,其中展示了解决您问题的解决方案。当用户点击“定时”按钮时,它们会自动以1秒间隔保存照片这是它的代码。它肯定会帮助您,因为我可以以每秒1张的速度存储5张连续照片

请查看页面MyViewController.m,在获取数组中的图像后,您可以使用另一个队列上的某些函数将它们保存到相册中


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接