Из документации CIImage:
Хотя объект CIImage имеет связанные с ним данные изображения, он не является изображением. Вы можете думать об объекте CIImage как о «рецепте» изображения. Объект CIImage содержит всю информацию, необходимую для создания изображения, но Core Image на самом деле не отображает изображение, пока ему об этом не будет сообщено. Этот метод «ленивой оценки» позволяет Core Image работать максимально эффективно.
Это означает, что любая фильтрация, которую вы могли применить (или лучше запросить применить) к вашему CIImage
, на самом деле не будет применена до тех пор, пока вы не визуализируете изображение, что в вашем случае происходит при создании CGImageRef
. Это, вероятно, причина, по которой вы испытываете замедление.
Тем не менее, фильтрация на CIImage
, как правило, очень быстрый процесс, поэтому, исходя из размера вашего изображения, вы должны дать нам свое определение медленного.
Наконец, чтобы убедиться, что узкое место действительно находится там, где вы думаете, вы должны профиль ваше приложение с помощью инструментов.
Изменить
Я только что попытался создать пример проекта, который фильтрует поток изображений, поступающий с камеры устройства (960x540) на iPad3, применяя цветовой фильтр CIColorMap
, и я получаю более 60 кадров в секунду (~ 16 мс).
В зависимости от вашего приложения вы получите лучшую производительность, повторно используя CIContext
, ColorMapFilter
, inputGradientImage
(если они не меняются со временем) и обновляя только inputImage
на каждой итерации.
Например, вы должны вызывать prepareFrameFiltering
один раз, а затем многократно вызывать applyFilterToFrame:
для каждого кадра, который хотите обработать.
@property (nonatomic, strong) CIContext *context;
@property (nonatomic, strong) CIFilter *colorMapFilter;
- (void)prepareFrameFiltering {
self.context = [CIContext contextWithOptions:nil];
CIImage *colorMap = [CIImage imageWithCGImage:[UIImage imageNamed:@"gradient.jpg"].CGImage];
self.colorMapFilter = [CIFilter filterWithName:@"CIColorMap"];
[self.colorMapFilter setValue:colorMap forKey:@"inputGradientImage"];
}
- (void)applyFilterToFrame:(CIImage *)ciFrame {
// filter
[self.colorMapFilter setValue:ciFrame forKey:@"inputImage"];
CIImage *ciImageResult = [self.colorMapFilter valueForKey: @"outputImage"];
CGImageRef ref = [self.context createCGImage:ciImageResult fromRect:ciFrame.extent];
// do whatever you need
CGImageRelease(ref);
}
person
Tomas Camin
schedule
29.01.2015