Как сгенерировать гистограмму с помощью iOS GPUImage?

Работая над проектом https://github.com/luisespinoza/LEColorPicker, я пытаюсь сгенерировать гистограмму UIImage из произвольного входного UIImage с использованием проекта GPUImage (https://github.com/BradLarson/GPUImage).

Текущий код, который я использую, выглядит следующим образом:

- (NSDictionary*)dictionaryWithColorsPickedFromImage:(UIImage *)image
{
    GPUImageFilter *filter = [[GPUImageHistogramFilter alloc] initWithHistogramType:kGPUImageHistogramRGB];

    UIImage *filteredImage = [filter imageByFilteringImage:image];

    [UIImagePNGRepresentation(filteredImage) writeToFile:@"/Users/Luis/histogram.png" atomically:YES];

    return nil;
}

Проблема в том, что histogram.png приводит к появлению только черной линии для каждого входного изображения.

Итак, каким будет правильный код для генерации гистограммы UIImage с использованием iOS GPUImage?

1 ответ

Решение

Вы можете посмотреть пример FilterShowcase, чтобы увидеть, как это должно работать на практике.

GPUImageHistogramFilter принимает изображение и выводит изображение размером 256x3, которое кодирует гистограмму (его высота составляет 3 пикселя, поскольку высота 1 пиксель в конструкции кадрового буфера не допускается). Значения R, G и B сохраняются в соответствующих цветовых каналах в центральной полосе высотой 1 пиксель в центре этого изображения.

Чтобы визуализировать это, вам нужно будет использовать GPUImageHistogramGenerator и передать в него вывод GPUImageHistogramFilter. GPUImageHistogramGenerator создает визуальное представление ввода гистограммы в виде изображения. Вам нужно использовать -forceProcessingAtSize: установить размер для выходного изображения GPUImageHistogramGenerator, потому что он не имеет установленного размера по умолчанию.

Еще одно предостережение: вам нужно иметь какой-то фиктивный фильтр между вашим входным изображением и GPUImageHistogramFilter. GPUImageHistogramFilter в настоящее время полагается на glReadPixels() и это работает только для визуализированного контента, а не для непосредственно загруженных изображений или видеокадров.

Код, используемый в FilterShowcase для этого, выглядит следующим образом:

        filter = [[GPUImageHistogramFilter alloc] initWithHistogramType:kGPUImageHistogramRGB];

        GPUImageGammaFilter *gammaFilter = [[GPUImageGammaFilter alloc] init];
        [videoCamera addTarget:gammaFilter];
        [gammaFilter addTarget:filter];

        GPUImageHistogramGenerator *histogramGraph = [[GPUImageHistogramGenerator alloc] init];

        [histogramGraph forceProcessingAtSize:CGSizeMake(256.0, 330.0)];
        [filter addTarget:histogramGraph];

        GPUImageAlphaBlendFilter *blendFilter = [[GPUImageAlphaBlendFilter alloc] init];
        blendFilter.mix = 0.75;            
        [blendFilter forceProcessingAtSize:CGSizeMake(256.0, 330.0)];

        [videoCamera addTarget:blendFilter];
        [histogramGraph addTarget:blendFilter];

        [blendFilter addTarget:filterView];

Это накладывается на визуализацию сгенерированной гистограммы поверх видео с входящей камеры.

Другие вопросы по тегам