Оптимизация скорости фотосъемки с iPhone, UIImagePickerController - PullRequest
0 голосов
/ 03 марта 2011

Я использую UIImagePickerController в моем приложении. Кто-нибудь использовал какие-либо приемы оптимизации для задержки фотосъемки? Мне не нужно хранить их в библиотеке. Я просто хочу захватить данные пикселей и уничтожить объект изображения после выполнения расчета.

Кроме того, есть ли способ скрыть объектив при его загрузке?

(В худшем случае я мог замаскировать объектив при запуске камеры и замаскировать замороженное изображение при сохранении / расчете.)

РЕДАКТИРОВАТЬ: Я уже установил showsCameraControls = NO;. Это скрывает эффект объектива между снимками, но не влияет на наличие анимации объектива при запуске камеры.

1 Ответ

5 голосов
/ 03 марта 2011

Вы подключены к UIImagePickerController?Начиная с iOS 4, AVFoundation позволяет получать прямой поток изображений с камеры при любом поддерживаемом разрешении видео, без предписанного пользовательского интерфейса, поэтому нет эффекта линзы, а на iPhone 4 вы можете получить изображение до 720p беззадержка;на более ранних устройствах вы можете получить 480p.

Сессия 409 видеороликов WWDC 2010, доступных по адресу здесь - хорошее место для начала.Вы захотите создать AVCaptureSession, присоединить подходящий AVCaptureDevice через AVCaptureDeviceInput, добавить AVCaptureVideoDataOutput и назначить очередь отправки, в которую вы будете передавать данные.В итоге вы получите CVImageBufferRef, который непосредственно предоставляет необработанные данные пикселей.

РЕДАКТИРОВАТЬ: пример кода Apple, по-видимому, отсутствует, я склонен использовать примерно следующее:

AVCaptureSession *session;
AVCaptureDevice *device;
AVCaptureVideoDataOutput *output;

// create a capture session
session = [[AVCaptureSession alloc] init];
session.sessionPreset = ...frame quality you want...;

// grab the default video device (which will be the back camera on a device
// with two), create an input for it to the capture session
NSError *error = nil;
device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput 
                                    deviceInputWithDevice:device error:&error];

// connect the two
[session addInput:input];

// create an object to route output back here
output = [[AVCaptureVideoDataOutput alloc] init];
[session addOutput:output];

// create a suitable dispatch queue, GCD style, and hook 
// self up as the delegate
dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
[output setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);

// set 32bpp BGRA pixel format
output.videoSettings =
        [NSDictionary 
            dictionaryWithObject:
                             [NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
            forKey:(id)kCVPixelBufferPixelFormatTypeKey];

[session startRunning];

ЭтоЗатем я начну доставлять CMSampleBuffers в ваш captureOutput: didOutputSampleBuffer: fromConnection: в созданную вами очередь отправки (т. е. в отдельный поток).Очевидно, что производственный код будет иметь гораздо больше проверок работоспособности и результатов, чем приведенный выше.

В следующем примере кода принимается входящий CMSampleBuffer, который содержит видеокадр, и преобразует его в CGImage, а затем отправляет его в основной потокгде в моем тестовом коде он конвертируется в UIImage и устанавливается как вещь внутри UIImageView, доказывая, что все это работает:

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

// lock momentarily, to get enough details to create a CGImage in the future...
CVPixelBufferLockBaseAddress(imageBuffer, 0);
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);

CVPixelBufferUnlockBaseAddress(imageBuffer, 0);

// create a CGImageRef
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = 
    CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colourSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
CGContextRelease(contextRef);
CGColorSpaceRelease(colourSpace);

[self performSelectorOnMainThread:@selector(postCGImage:) withObject:[NSValue valueWithPointer:imageRef] waitUntilDone:YES];
CGImageRelease(imageRef);

Я объединил объект, который обычно использую для получениявидео кадры и некоторые вещи из контроллера представления, например;надеюсь, я не допустил ошибок.

...