【问题标题】:iPhone camera shoots photos rapidly, but has problems saving themiPhone相机快速拍摄照片,但无法保存照片
【发布时间】:2011-09-30 03:01:33
【问题描述】:

我正在尝试用相机快速拍摄和保存照片,就像 iPhone 一样快。问题是他们直到最后才保存,然后它会永远保存,或者大约 1/2 到 3/4 根本不保存(Write busy 错误或-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL)。

我敢打赌,我只是让手机的内存过载,但我想不出一种有效处理它的方法。标准的 iPhone 相机应用程序可以很好地处理它 - 以几乎每秒 1 张照片的速度拍摄,它可以毫无问题地保存。

关于如何更好地管理进程/内存以便它可以随时保存但仍能快速拍摄的任何想法?

这是我的一些代码。每当self.readyToTake = YES 时调用takePicture

- (void)takePicture { self.delegate = 自我; [超级拍照]; self.readyToTake = 否; } - (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 { 如果(错误) { NSLog([NSString stringWithFormat:@"** 错误保存照片: %@", [错误本地化描述]]); } }

感谢您的帮助!


编辑

如果我在保存之前将照片调整为更小的尺寸,例如 480x640,我可以快速保存。但是,我想捕获并保存全尺寸图像。原生相机应用似乎可以很好地处理它。

【问题讨论】:

    标签: iphone camera


    【解决方案1】:

    你可以这样做。 即,仅在保存上一张照片后才能拍摄下一张照片。 还引入了自动释放池进行内存管理。

    - (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 秒才能保存。
    • 我们可以在一些后台线程中执行保存功能...但如果需要 3-5 秒,那么它可能会导致进程垃圾...这完全取决于我猜的硬件。 ..
    【解决方案2】:

    我会尝试的第一件事是将这些调用异步卸载到调度队列:

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

    【讨论】:

    • 谢谢,艺术。使用调度队列比以前节省了大约 2 倍,但仍然节省了大约 1/3,其余的要么用Write busy 要么-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL。有什么想法吗?
    • 使用AVCaptureSession确实可以快速拍摄照片,但照片保存时使用相同的UIImageWriteToSavedPhotosAlbum。他们可以使用AVCaptureSession 更快地保存图像的原因是图像只有 480x640。如果我将它们调整到那么小,我可以使用当前方法快速保存,但我想要正常尺寸的照片。感谢您的帮助和任何其他想法!
    • 实际上,您可以使用AVCaptureSessionAVCaptureSessionPresetPhoto 从传感器获取全尺寸照片,image:didFinishSavingWithError: 你在做什么@
    • 要尝试的另一件事是使用AssetsLibrary ...查看我的编辑。
    【解决方案3】:

    developer.apple.com 网站上有一个最好的示例应用程序,其中显示了您的问题的解决方案,当用户点击“定时”按钮here is its code 时,它们会自动将照片保存 1 秒间隔@它肯定会帮助您我可以以每秒 1 的速度存储 5 张连续照片

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多