核心图像滤镜背景

Core Image Filter Background

我正在尝试使用 Core Image 创建直方图。我成功地让它显示(下面的代码)。但是,直方图的背景是灰色的。我怎样才能弄清楚?

    //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];

据我所知,没有参数可以自定义此过滤器生成的直方图的背景颜色。本来就是这样的。相同的颜色甚至出现在 Apple 的 documentation of the filter 上(查看示例输出)。

我能想到两种可能的解决方案:

  1. 编写自己的代码或寻找其他库来生成直方图;一种可以让您更好地控制输出的方法。
  2. 如果您希望保留 CoreImage 代码,则需要对直方图图像执行额外的处理。一种可能的解决方案是遍历其像素并检查直方图背景的特定灰色(137、137、137),然后将它们设置为透明。我不知道这是否是最佳解决方案,但它确实有效。

继续第二种解决方案,这里有一种方法可以将灰色变为透明:

-(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;
}

现在在您的最终图像上调用此方法:

resized = [self removeColorFromImage:resized grayLevel:137]; 

顺便说一句,创建直方图图像需要一行:

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