Камера iPhone быстро снимает фотографии, но не может их сохранить

Я пытаюсь быстро делать и сохранять фотографии с помощью камеры, так быстро, как это может делать 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]]);
    }
}

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


ИЗМЕНИТЬ

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


person James Skidmore    schedule 07.07.2011    source источник


Ответы (3)


arrow_upward
2
arrow_downward

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

- (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;
}
person Ilanchezhian    schedule 07.07.2011
comment
Проблема с включением следующей фотографии после сохранения предыдущей заключается в том, что камера больше не снимает быстро. Для сохранения большинства фотографий требуется около 3-5 секунд. - person James Skidmore; 07.07.2011
comment
Мы можем выполнить функцию сохранения в каком-то фоновом потоке ... но все же, если это займет 3-5 секунд, это может привести к ненужному процессу ... Все зависит от оборудования, я думаю ... - person Ilanchezhian; 08.07.2011

arrow_upward
1
arrow_downward

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

- (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
     }];
}
person Art Gillespie    schedule 19.04.2012
comment
Спасибо, Art. Использование очереди отправки экономит примерно в 2 раза больше, чем раньше, но по-прежнему экономит около 1/3, а остальные либо приходят с Write busy, либо -[NSKeyedUnarchiver initForReadingWithData:]: data is NULL. Есть предположения? - person James Skidmore; 19.04.2012
comment
Использование AVCaptureSession действительно позволяет делать фотографии в быстром темпе, но фотографии сохраняются (с примерами, которые я видел) с использованием того же UIImageWriteToSavedPhotosAlbum. Причина, по которой они могут намного быстрее сохранять с AVCaptureSession, заключается в том, что изображения имеют размер только 480x640. Я могу сохранить так же быстро, используя текущий метод, если я уменьшу их размер до такого маленького, но мне нужны фотографии нормального размера. Я ценю вашу помощь и любые другие идеи! - person James Skidmore; 19.04.2012
comment
Фактически, вы можете получить полноразмерные фотографии с сенсора, используя AVCaptureSession с AVCaptureSessionPresetPhoto Что вы делаете в image:didFinishSavingWithError: - person Art Gillespie; 19.04.2012
comment
Еще можно попробовать использовать AssetsLibrary ... См. Мою правку. - person Art Gillespie; 19.04.2012

arrow_upward
1
arrow_downward

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

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

person The iOSDev    schedule 25.04.2012