How to make a Core Image kernel program running on the CLI

Here’s a CLI program which lets you apply a Core Image kernel to image files to generate a new image file. Example of use to average two images:

swift main.swift 'return (sample(i1, samplerCoord(i1)) + sample(i2, samplerCoord(i2))) / 2.0;' /Users/jim/Lenna.png /Users/jim/shapes.png /Users/jim/dev/kern_blend/out.png
import Foundation
import CoreImage
import AppKit
let kernelFunctionBody = CommandLine.arguments[1]
var imageArguments : [CIImage] = []
var outputRect = CGRect(x: 0, y: 0, width: 0, height: 0)
var kernelParams : [String] = []
for i in 2...CommandLine.arguments.count-2 {
  let nsImage = NSImage(contentsOfFile: CommandLine.arguments[i])!
  let cgImage = nsImage.cgImage(forProposedRect: nil, context: nil, hints: [:])!
  imageArguments.append(CIImage(cgImage: cgImage))
  outputRect = CGRect(x: 0, y: 0, width: cgImage.width, height: cgImage.width)
  kernelParams.append("sampler i" + String(i-1))
}
let kernelParamString = kernelParams.joined(separator: ", ")
let kernels = CIKernel.kernels(with: "kernel vec4 k(" + kernelParamString + ") {" + kernelFunctionBody + "}")!
let myKernel = kernels[0]
if #available(OSX 10.11, *) {
  let outputImage = myKernel.apply(
    withExtent: outputRect,
    roiCallback: { (Int32, CGRect) -> CGRect in return outputRect },
    arguments: imageArguments
  )!
  let rep = NSBitmapImageRep(ciImage: outputImage.cropping(to: outputRect))
  let imageData = rep.representation(using: NSBitmapImageFileType.PNG, properties: [:])!
  try! imageData.write(to: URL.init(string: "file:" + CommandLine.arguments[CommandLine.arguments.count-1])!, options: NSData.WritingOptions.atomic)
} else {
  print("Must have 10.11 or higher.")
}
Tagged .

Similar posts

More by Jim

👋 I'm Jim, a full-stack product engineer. Want to build an amazing product and a profitable business? Read more about me or Get in touch!

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