Core Image Filter Background

1.5k views Asked by At

I am trying to create a Histogram using Core Image. I successfully got it to display (code below). However, the background of the histrogram is gray. How can I get it to be clear?

    //Show Histogram
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CFDictionaryRef attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, sampleBuffer, kCMAttachmentMode_ShouldPropagate);
CIImage *ciImage = [[CIImage alloc] initWithCVPixelBuffer:pixelBuffer options:(__bridge NSDictionary *)attachments];


NSUInteger count = 256;
count = count <= 256 ? count : 256;
count = count >= 1 ? count : 1;


NSDictionary *params = @{kCIInputImageKey: ciImage,
                         kCIInputExtentKey: [CIVector vectorWithCGRect:[ciImage extent]],
                         @"inputCount": @(count), @"inputScale": @(100),
                         };

CIFilter *filter = [CIFilter filterWithName:@"CIAreaHistogram"
                        withInputParameters:params];


CIImage *outImage = [filter outputImage];
//---------------------------------------------

CIContext *context = [CIContext contextWithOptions:nil];

NSDictionary *params2 = @{
                          kCIInputImageKey: outImage,
                          };
CIFilter *filter2 = [CIFilter filterWithName:@"CIHistogramDisplayFilter"
                         withInputParameters:params2];

CIImage *outputImage = [filter2 outputImage];
CGRect outExtent = [outputImage extent];
CGImageRef cgImage = [context createCGImage:outputImage
                                   fromRect:outExtent];


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

// resize
UIImage *resized = [self resizeImage:outImage2
                         withQuality:kCGInterpolationNone
                                rate:2.5];
2

There are 2 answers

7
Artal On BEST ANSWER

As far as I know there is no parameter that can customize the background color of the histogram produced by this filter. It was meant to be this way. The same color even appears on Apple's documentation of the filter (look at the sample output).

I can think of two possible solutions:

  1. Write your own code or look for another library to produce the histogram; one that gives you more control over the output.
  2. If you wish to keep with your CoreImage code, you'll need to perform additional processing on the histogram image. A possible solution would be to go over its pixels and check for the specific gray color of the histogram background (137, 137, 137), then set them to be transparent. I don't know if that's the best solution, but it works.

Going with the second solution, here's a method that will turn the gray color to transparent:

-(UIImage*)removeColorFromImage:(UIImage*)sourceImage grayLevel:(int)grayLevel
{
    int width = sourceImage.size.width * sourceImage.scale;
    int height = sourceImage.size.height * sourceImage.scale;
    CGFloat scale = sourceImage.scale;

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedFirst);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), sourceImage.CGImage);

    unsigned int *colorData = CGBitmapContextGetData(context);

    for (int i = 0; i < width * height; i++)
    {
        unsigned int color = *colorData;

        short a = color & 0xFF;
        short r = (color >> 8) & 0xFF;
        short g = (color >> 16) & 0xFF;
        short b = (color >> 24) & 0xFF;

        if ((r == grayLevel) && (g == grayLevel) && (b == grayLevel))
        {
            a = r = g = b = 0;
            *colorData = (unsigned int)(r << 8) + ((unsigned int)(g) << 16) + ((unsigned int)(b) << 24) + ((unsigned int)(a));
        }

        colorData++;
    }

    CGImageRef output = CGBitmapContextCreateImage(context);
    UIImage* retImage = [UIImage imageWithCGImage:output scale:scale orientation:UIImageOrientationUp];

    CGImageRelease(output);
    CGContextRelease(context);

    return retImage;
}

Now call this method on your final image:

resized = [self removeColorFromImage:resized grayLevel:137]; 
0
James Bush On

By the way, it takes one line to create a histogram image:

CIImage *histogramImage = [CIFilter filterWithName:@"CIHistogramDisplayFilter" keysAndValues:kCIInputImageKey, self.inputImage, @"inputHeight", @100.0, @"inputHighLimit", @1.0, @"inputLowLimit", @0.0, nil].outputImage;