Проблемы с созданием UIImage из CIImage в iOS5

Я использую фреймворк AVFoundation. В моем примере делегата буфера у меня есть следующий код:

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
     CVPixelBufferRef pb = CMSampleBufferGetImageBuffer(sampleBuffer);
     CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pb];
     self.imageView.image = [UIImage imageWithCIImage:ciImage];
}

Я могу использовать CIImage для запуска детектора лиц и т. д., но он не отображается в UIImageView... imageView остается белым. Любые идеи относительно проблемы? Я использую следующее для настройки сеанса:

    self.session = [[AVCaptureSession alloc] init];
self.session.sessionPreset = AVCaptureSessionPreset640x480;
self.videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil]; 
self.frameOutput = [[AVCaptureVideoDataOutput alloc] init];
self.frameOutput.videoSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey];

person user491880    schedule 17.10.2011    source источник


Ответы (4)


Это может помочь. У меня была такая же проблема (изображение не отображалось на экране) с этим кодом:

CIImage *image = [[CIImage alloc] initWithImage:[UIImage imageNamed:@"mushroom.jpg"]];

theImageView.image = [UIImage imageWithCIImage:image];

Однако после изменения кода на этот он теперь работает правильно:

CIImage *image = [[CIImage alloc] initWithImage:[UIImage imageNamed:@"mushroom.jpg"]];

CIContext *context = [CIContext contextWithOptions:nil];

theImageView.image = [UIImage imageWithCGImage:[context createCGImage:image fromRect:image.extent]];

Подробнее о CIContext см. здесь: http://developer.apple.com/library/ios/#DOCUMENTATION/GraphicsImaging/Reference/QuartzCoreFramework/Classes/CIContext_Class/Reference/Reference.html#//apple_ref/occ/cl/CIContext

person spybart    schedule 17.10.2011
comment
Спасибо - это действительно позволяет мне нарисовать изображение. Однако происходит утечка памяти, что приводит к сбою приложения через несколько секунд. - person user491880; 17.10.2011
comment
Да, я еще не особо вникал в это. Я уверен, что в какой-то момент вам придется выпустить контексты или CGImageRef. Также я уверен, что описанный выше метод не является практичным способом использования представлений CIImage. Я планирую посмотреть видео «Использование основного образа в iOS и Mac OS X» (которое находится на сайте Apple Developer, видеозаписи сеансов WWDC 2011) завтра и узнать больше, я напишу вам, если узнаю что-нибудь полезное. - person spybart; 17.10.2011
comment
Я рекомендую вам также посмотреть это видео и/или просмотреть слайды презентации, так как в них объясняется, как использовать Core Image, и подробно рассказывается о контекстах, когда использовать ЦП/ГП и многое другое. - person spybart; 18.10.2011
comment
Я также нашел это полезным: Руководство по программированию OpenGL ES для iOS developer.apple.com/library/ios/#documentation/3DDrawing/ - person spybart; 18.10.2011
comment
Не могли бы вы объяснить, почему это работает по сравнению с imageWithCIImage? Я согласен с вами, я просто не могу понять, почему один только imageWithCIImage не работает, как это должно быть в соответствии с документами. - person akaru; 09.11.2011
comment
Похоже, что imageWithCGImage не сохраняет данный CGImage. Когда вы вызываете _create_CGImage, вы получаете неавтоматически выпущенный объект, поэтому он не освобождается. Вероятно, это причина того, что он работает, но также и протекает... - person Oded Ben Dov; 03.12.2011
comment
@akaru вот что в ссылке UIImage говорится о его свойстве CGImage: если объект UIImage был инициализирован с использованием объекта CIImage, значение свойства равно NULL. и похоже, что UIImageView пытается получить доступ к CGImage UIImage в своей реализации. это также похоже на функцию UIImagePNGRepresentation — она возвращает nil, если UIImage не основан на CGImage. Но +[CIContext createCGImage:] просто делает то, что говорит — создает CGImage, так что работает. - person Russian; 07.01.2012
comment
Хороший ответ Тулки, @akaru, вы должны выбрать этот ответ. - person C4 - Travis; 10.03.2012
comment
@ C4-Трэвис, это не мой вопрос, на который я должен отвечать. - person akaru; 07.01.2013
comment
@akaru ой! простите за это. - person C4 - Travis; 08.01.2013
comment
@Russian спасибо, что нашли объяснение! Ни за что бы не догадался сам. Кроме того, я укажу, что мы должны использовать alloc/init вместо удобных методов для создания CIImage, чтобы заставить это работать. - person windson; 18.05.2013
comment
@spybart Утечки вашего кода: [context createCGImage...] создает CGContextRef, который должен быть выпущен (даже в ARC). Поскольку вы не присваиваете его переменной, вы не можете его освободить, и здесь вы теряете довольно много памяти. - person xaphod; 17.08.2016

Вот один из способов, которым я заставил его работать:

CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef ref = [context createCGImage:result fromRect:ciImage.extent];
self.imgView.image = [UIImage imageWithCGImage:ref scale:1.0 orientation:UIImageOrientationRight];
CGImageRelease(ref);

Примечание. Многократное создание контекста очень плохо и фактически вызывает утечку памяти. Вы должны просто создать контекст один раз как свойство в своем экземпляре класса и использовать его повторно!

person user491880    schedule 17.10.2011

Вот полный пример кода, который я использовал в своих проектах.

- (UIImage *)makeUIImageFromCIImage:(CIImage *)ciImage {
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgImage = [context createCGImage:ciImage fromRect:[ciImage extent]];

    UIImage* uiImage = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);

    return uiImage;
}

CIImage — это, по сути, рецепт изображения. Вы столкнетесь с проблемами, если попытаетесь напрямую преобразовать CIImage в UIImage. Например, вызов

NSData * UIImageJPEGRepresentation (
   UIImage *image,
   CGFloat compressionQuality
);

вернет nil.

person JVillella    schedule 18.03.2015
comment
гениально, спасибо!!! Интересно, почему Apple предоставляет [UIImage imageWithCIImage], если он редко работает. Спасибо, Apple. - person Duck; 20.04.2017
comment
С помощью этого метода я столкнулся с некоторыми очень тонкими проблемами искажения цвета и альфа-смешивания, которые были устранены путем установки контекста цветового пространства = [CIContext contextWithOptions:@{kCIContextWorkingColorSpace : [NSNull null]}]; - person user1055568; 08.10.2017
comment
Спасибо @user1055568, это была важная информация, которая нам была нужна. - person Airsource Ltd; 08.02.2019

person    schedule
comment
Не работает для меня. Я создал CIImage не так, как показано здесь. - person Automatico; 28.12.2015