Learn more about Israeli war crimes in Gaza, funded by the USA, Germany, the UK and others.

What is CIColorKernel?

I’ve showed some uses of CIKernel, each of which produces an output pixel by transforming one pixel of some input images. To get the input pixels, I used code like this:

vec4 i1_px = sample(image1, samplerCoord(image1));
vec4 i2_px = sample(image2, samplerCoord(image2));

Kernels of this form, which only examine one point of the input image, can instead be expressed as CIColorKernels. Here’s a CIColorKernel which composes two images with some opacity:

kernel vec4 alpha_compose(__sample i1_px, __sample i2_px, float image2_opacity) {
  return i1_px*(1.0 - image2_opacity) + i2_px*image2_opacity;
}

Instead of the input being a sampler (an image), the input to a color kernel is a __sample, which is a vec4 representing a pixel sample of an input image. A color kernel is strictly less flexible than a general kernel, which allows for some optimizations when executing it.

Here’s the example kernel in use:

import Foundation
import CoreImage
import AppKit
let myKernel = CIColorKernel(string:
    "kernel vec4 alpha_compose(__sample i1_px, __sample i2_px, float image2_opacity) { " +
    "  return i1_px*(1.0 - image2_opacity) + i2_px*image2_opacity;" +
    "}")!
func ciImageFromPath(path: String) -> CIImage {
    let nsImage = NSImage(contentsOfFile: path)!
    let cgImage = nsImage.cgImage(forProposedRect: nil, context: nil, hints: [:])!
    return CIImage(cgImage: cgImage)
}
let inputImage1 = ciImageFromPath(path: "/Users/jim/shapes.png")
let inputImage2 = ciImageFromPath(path: "/Users/jim/Lenna.png")
let outputRect = CGRect(x: 0, y: 0, width: inputImage1.cgImage!.width, height: inputImage1.cgImage!.height)
let outputImage = myKernel.apply(
    withExtent: outputRect,
    roiCallback: { (Int32, CGRect) -> CGRect in return outputRect },
    arguments: [inputImage1, inputImage2, 0.2]
)!
let rep = NSBitmapImageRep(ciImage: outputImage.cropping(to: outputRect))
let imageData = rep.representation(using: NSBitmapImageFileType.PNG, properties: [:])!
try! imageData.write(to: URL.init(string: "file:/Users/jim/output.png")!, options: NSData.WritingOptions.atomic)
Tagged .

Similar posts

More by Jim

Want to build a fantastic product using LLMs? I work at Granola where we're building the future IDE for knowledge work. Come and work with us! Read more or get in touch!

This page copyright James Fisher 2017. Content is not associated with my employer. Found an error? Edit this page.