Я пытаюсь быстро делать и сохранять фотографии с помощью камеры, так быстро, как это может делать 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, у меня не возникнет проблем с быстрым сохранением. Однако я хочу снимать и сохранять полноразмерные изображения. Родное приложение камеры, кажется, справляется с этим нормально.
Ответ 1 · рейтинг 2 · Ilanchezhian
вы можете сделать это. т.е. разрешить делать следующую фотографию только после сохранения предыдущей. Также представьте пул автозапуска для управления памятью.
- (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;
}
Ответ 2 · рейтинг 1 · Art Gillespie
Первое, что я попробую, - это асинхронно выгрузить эти вызовы в очередь отправки:
- (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
}];
}
Ответ 3 · рейтинг 1 · The iOSDev
на сайте developer.apple.com есть один лучший пример приложения, в котором показано решение вашей проблемы. Они автоматически сохраняют фотографии с интервалом в 1 секунду, когда пользователь нажимает кнопку "по времени" вот его код, он, безусловно, поможет вам, так как я могу хранить 5 фотографий со скоростью 1 / сек.
См. Страницу MyViewController.m, и после получения изображений в массиве вы можете сохранить их в фотоальбом с помощью какой-либо функции в другой очереди.