Liron
Liron

Reputation: 2032

UIImage color correction

I am using AVFoundation to play a video by creating a CGImage from the AVFoundation callback, creating a UIImage from the CGImage and then displaying the UIImage in a UIImageView.

I want to apply some color correction to the images before I display them on the screen. What is the best way to colorize the images I'm getting?

I tried using the CIFilters, but that requires me to first create a CIImage from AVFoundation, then colorise it, then create a CGImage and then create a UIImage, and I'd rather avoid the extra step of creating the CIImage if possible.

Additionally, it doesn't seem like the performance of the CIFilters is fast enough - at least not when also having to create the additional CIImage. Any suggestions for a faster way to go about doing this?

Thanks in advance.

Upvotes: 1

Views: 398

Answers (1)

Liron
Liron

Reputation: 2032

It seems that using an EAGLContext instead of a standard CIContext is the answer. That gives fast enough performance in creating the colorized images for my needs.

Simple code example here:

On Init:

NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
[options setObject: [NSNull null] forKey: kCIContextWorkingColorSpace];
m_EAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
m_CIContext = [CIContext contextWithEAGLContext:m_EAGLContext options:options];

Set the color:

-(void)setColorCorrection:(UIColor*)color
{  
  CGFloat r,g,b,a;
  [color getRed:&r green:&g blue:&b alpha:&a];

  CIVector *redVector = [CIVector vectorWithX:r Y:0 Z:0];
  CIVector *greenVector = [CIVector vectorWithX:0 Y:g Z:0];
  CIVector *blueVector = [CIVector vectorWithX:0 Y:0 Z:b];

  m_ColorFilter = [CIFilter filterWithName:@"CIColorMatrix"];
  [m_ColorFilter setDefaults];
  [m_ColorFilter setValue:redVector forKey:@"inputRVector"];
  [m_ColorFilter setValue:greenVector forKey:@"inputGVector"];
  [m_ColorFilter setValue:blueVector forKey:@"inputBVector"];
}

On each video frame:

CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
CGImageRef cgImage = nil;

CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];

[m_ColorFilter setValue:ciImage forKey:kCIInputImageKey];
CIImage *adjustedImage = [m_ColorFilter valueForKey:kCIOutputImageKey];

cgImage = [m_CIContext createCGImage:adjustedImage fromRect:ciImage.extent];

Upvotes: 1

Related Questions