Я пытаюсь отобразить UIImage в режиме реального времени с камеры, и кажется, что мой UIImageView не отображает изображение должным образом. Это метод, который AVCaptureVideoDataOutputSampleBufferDelegate
должен реализовать
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
// Create a UIImage from the sample buffer data
UIImage *theImage = [self imageFromSampleBuffer:sampleBuffer];
// NSLog(@"Got an image! %f %f", theImage.size.width, theImage.size.height);
// NSLog(@"The image view is %@", imageView);
// UIImage *theImage = [[UIImage alloc] initWithData:[NSData
// dataWithContentsOfURL:[NSURL
// URLWithString:@"http://farm4.static.flickr.com/3092/2915896504_a88b69c9de.jpg"]]];
[self.session stopRunning];
[imageView setImage: theImage];
}
Чтобы избавиться от простых проблем:
- Использование UIImagePickerController не является опцией (в конце концов мы действительно будем делать что-то с изображением)
- Я знаю, что вызывается обработчик (сделаны вызовы NSLog, и я вижу вывод)
- Я знаю, что объявления IBOutlet настроены правильно. Если я использую приведенный выше код для загрузки произвольного изображения из Интернета вместо простой отправки
setImage:theImage
в imageView, изображение будет загружено правильно (и второй вызов NSLog сообщает об отличном от nil объекте).
- По крайней мере, в базовой степени, изображение, которое я получаю с
imageFromSampleBuffer:
, в порядке, поскольку NSLog сообщает, что его размер равен 360x480, что является ожидаемым размером.
Код, который я использую, - это недавно опубликованный фрагмент AVFoundation
от Apple, доступный здесь .
В частности, я использую код, который устанавливает объект AVCaptureSession
и друзей (о которых я очень мало понимаю) и создает объект UIImage из буферов Core Video (это метод imageFromSampleBuffer
).
Наконец, я могу заставить приложение аварийно завершить работу, если я попытаюсь отправить drawInRect:
в простой подкласс UIView с UIImage
, возвращаемым imageFromSamplerBuffer
, в то время как оно не падает, если я использую UIImage
из URL, как указано выше. Вот трассировка стека отладчика внутри сбоя (я получаю сигнал EXC_BAD_ACCESS):
#0 0x34a977ee in decode_swap ()
#1 0x34a8f80e in decode_data ()
#2 0x34a8f674 in img_decode_read ()
#3 0x34a8a76e in img_interpolate_read ()
#4 0x34a63b46 in img_data_lock ()
#5 0x34a62302 in CGSImageDataLock ()
#6 0x351ab812 in ripc_AcquireImage ()
#7 0x351a8f28 in ripc_DrawImage ()
#8 0x34a620f6 in CGContextDelegateDrawImage ()
#9 0x34a61fb4 in CGContextDrawImage ()
#10 0x321fd0d0 in -[UIImage drawInRect:blendMode:alpha:] ()
#11 0x321fcc38 in -[UIImage drawInRect:] ()
РЕДАКТИРОВАТЬ: Вот еще некоторая информация о UIImage, возвращаемом этим битом кода.
Используя описанный метод здесь , я могу добраться до пикселей и распечатать их, и они на первый взгляд выглядят нормально (например, каждое значение в альфа-канале равно 255). Однако, что-то немного не так с размерами буфера. Изображение, которое я получаю с Flickr с этого URL, имеет размер 375x500, и его [pixelData length]
дает мне 750000 = 375*500*4
, что является ожидаемым значением. Однако пиксельные данные изображения, возвращаемые из imageFromSampleBuffer:
, имеют размер 691208 = 360*480*4 + 8
, поэтому в данных пикселей есть 8 дополнительных байтов. CVPixelBufferGetDataSize
само возвращает это значение off-by-8. На мгновение я подумал, что это может быть связано с размещением буферов в совмещенных позициях в памяти, но 691200 кратно 256, так что это тоже не объясняется. Это несоответствие размеров - единственное различие, которое я могу сказать между двумя UIImages, и оно может быть причиной проблемы. Тем не менее, нет никаких причин выделять дополнительные памяти для буфера, что должно вызвать нарушение EXC_BAD_ACCESS.
Большое спасибо за любую помощь, и дайте мне знать, если вам нужна дополнительная информация.