Камера iPhone снимает фотографии быстро, но у них проблемы с сохранением - PullRequest
3 голосов
/ 07 июля 2011

Я пытаюсь снимать и сохранять фотографии с помощью камеры так быстро, как только может iPhone. Проблема в том, что они не сохраняются до конца, а потом это длится вечно, или примерно от 1/2 до 3/4 вообще не сохраняются (Write busy ошибка или -[NSKeyedUnarchiver initForReadingWithData:]: data is NULL).

Бьюсь об заклад, я просто перегружаю память телефона, но не могу придумать, как с этим справиться. Стандартное приложение камеры iPhone может справиться с этим просто - снимайте со скоростью почти 1 фото в секунду, и это без проблем сохранится.

Есть какие-нибудь идеи о том, как лучше управлять процессом / памятью, чтобы он мог сохранять в процессе, но при этом быстро снимать?

Вот немного моего кода. takePicture вызывается всякий раз, когда self.readyToTake = YES.

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

Спасибо за помощь!


EDIT

Если перед изменением я изменю размеры фотографий до гораздо меньших размеров, например 480x640, у меня не возникнет проблем с быстрым сохранением. Тем не менее, я хочу захватить и сохранить полноразмерные изображения. Нативное приложение Camera, кажется, прекрасно с этим справляется.

Ответы [ 3 ]

2 голосов
/ 07 июля 2011

вы можете сделать это так.то есть, разрешить делать следующий снимок только после сохранения предыдущего снимка.Также введен пул автоматического выпуска для управления памятью.

- (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;
}
1 голос
/ 25 апреля 2012

есть один лучший пример приложения на сайте developer.apple.com, в котором показано решение вашей проблемы, в котором они автоматически сохраняют фотографии с интервалом в 1 секунду, когда пользователь нажимает кнопку «по времени» вот ее код это, безусловно, поможет вам, поскольку я могу хранить 5 последовательных фотографий со скоростью 1 / секунда

Пожалуйста, см. Страницу MyViewController.m и после получения изображений в массиве вы можете сохранить их в фотоальбом, используя какую-то функцию на другойочередь

1 голос
/ 19 апреля 2012

Первое, что я попробую, это асинхронно разгрузить эти вызовы в очередь отправки:

- (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

EDIT

Вы также можете попробовать использовать 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
     }];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...