Search code examples
iosobjective-cswiftcifilteravcapturedevice

Add Over Saturation Effect on AVCaptureDevice in iOS


I have implemented custom camera into my app. So, I am creating this camera using AVCaptureDevice. Also I have set GrayScale on this custom camera using Set GrayScale on Output of AVCaptureDevice in iOS this.

Now I want to add over saturation effect on camera. "Oversaturation hint" should be calculated according to formula provided. (convert overexposure pixel (R,G,B >= 255) to yellow (RGB 255,255,0)).

I want exact effect which is showing in following Image.

enter image description here

I am creating GrayScale using following code:-

let sepiaColor = CIColor(
    red: 1.0 / 0.30078125,
    green: 1.0 / 0.5859375,
    blue: 1.0 / 0.11328125
)

filter = CIFilter(
    name: "CIColorMonochrome",
    withInputParameters: [
        "inputColor" : sepiaColor,
        "inputIntensity" : 1.0
    ]
)

How can I create this over saturation effect using CIFilter.? I have reviewed Core Image Filter Reference document for CIFilter. But didn’t get idea about How to create this effect using this. May be CIColorCrossPolynomial or CIColorMap are working for this.

Is there any way to create this effect on AVCaptureDevice.?

Any Help would be appreciated. :)


Solution

  • Your logic/algorithm:

    (convert overexposure pixel (R,G,B >= 255) to yellow (RGB 255,255,0))

    will go in the kernel, which is essentially the computation you want to perform on each pixel.

    Here's a simple filter I have written. In the if condition of the kernel, write your own condition. The then part already converts the pixel into (255, 255, 0).

    .h

    #import <CoreImage/CoreImage.h>
    
    @interface CustomFilter : CIFilter
    
    @property(nonatomic, retain) CIImage *inputImage;
    
    -(CIImage*)outputImage;
    
    @end
    

    .m

    #import "CustomFilter.h"
    
    @implementation CustomFilter
    
    -(CIColorKernel*)myKernel
    {
        static CIColorKernel *kernel = nil;
        static dispatch_once_t once;
        dispatch_once(&once, ^{
            kernel = [CIColorKernel kernelWithString:
                      @"kernel vec4 CustomFilter ( __sample s ) \n { \n if ( s.r + s.g + s.b < 0.1 ) \n { return s.rgba = vec4(1.0, 1.0, 0.0, 1.0); } \n else \n { return s.rgba; } \n }"];
        });
    
        return kernel;
    }
    
    -(CIImage*)outputImage
    {
        CGRect dod = _inputImage.extent;
        return [[self myKernel] applyWithExtent:dod arguments:@[_inputImage]];
    }
    
    @end