1

I recently upgraded to Xcode 10.2 and my CIColorKernel code does not work anymore. CIColorKernel function returns a nil and I get the warning - 'init(source:)' was deprecated in OS X 10.14: Core Image Kernel Language API deprecated.

Is Metal Shading Language the only available alternative to CIColorKernel? Looks like MSL require creating a separate file for the custom filter and I wanted to check if there are any better options.

// Create custom Kernel to replace gray color with black or white.
//Kernel is nil because 'init(source:)' was deprecated in OS X 10.14.

     let Kernel = CIColorKernel( source:
            "kernel vec4 replaceGrayWithBlackOrWhite(__sample grayImage) {" +
                "if (s.r > 0.25 && s.g > 0.25 && s.b > 0.25) {" +
                "    return vec4(0.0,0.0,0.0,1.0);" +
                "} else {" +
                "    return vec4(1.0,1.0,1.0,1.0);" +
                "}" +
            "}"
        )

// Apply the filter
        let blackAndWhiteImage = replaceGrayKernel?.apply(extent: ((grayImage?.extent)! ), arguments: [grayImage as Any])
matt
  • 515,959
  • 87
  • 875
  • 1,141
Ble21
  • 43
  • 6
  • Interesting. My kernels *work* in both iOS 12 and iOS 13 beta. Maybe because I'm still targeting iOS 9.0 as the base. A new project targeting iOS 13 yield the same error as you. If your project isn't a `SwiftUI` project, what happens if you target macOS 10.13? (And for the record, you probably should consider moving to Metal, even if targeting a lower OS version works..) –  Jun 19 '19 at 11:24
  • Good news! Found the issue. Will be editing my answer with the correct info. –  Jun 19 '19 at 16:31
  • another code which doesn't respect alpha https://gist.github.com/xhruso00/a3f8a9c8ae7e33b8b23d – Marek H Oct 17 '19 at 19:55

1 Answers1

-2

The issue isn't deprication, it's in your kernel code.

Try this:

let testKernel = CIColorKernel(source:
    "kernel vec4 replaceGrayWithBlackOrWhite(__sample grayImage) { " +
        "if (grayImage.r > 0.25 && grayImage.g > 0.25 && grayImage.b > 0.25) { " +
        "    return vec4(0.0,0.0,0.0,1.0);" +
        "} else { " +
        "    return vec4(1.0,1.0,1.0,1.0);" +
        "} " +
    "}"
)

The only things I changed were (1) I renamed Kernel to testKernel - shouldn't matter - and changed the if statement to check grayImage instead of s, which is how you set up the kernel signature. It's that second change that matters.

The way I create my custom kernels is to put the code in a file, register the CIFilter subclass for easy consumption, and then execute this:

let kernel = CIColorKernel(source: openKernelFile("myKernel"))

override var  outputImage: CIImage {
    return kernel!.apply(
        extent: inputImage.extent,
        arguments: [
            inputImage as Any,
        ])!
}

Note the kernel! force-unwrap. This means that when I test, my app stops execution immediately because kernel is nil. The way you code it, nil is an okay value in how you declare it.

Now, the reason you get the warning and I don't? I'm still targeting iOS 9+. (I actually found your issue in a test project where I'm upgrading to Metal and targeting iOS 11+. As long as you do not target iOS 12+, you'll not get the warning. If you look at how CIColorFilter is defined, you'll find this:

@available(iOS, introduced: 8.0, deprecated: 12.0, message: "Core Image Kernel Language API deprecated. (Define CI_SILENCE_GL_DEPRECATION to silence these warnings)")

I feel this is poor wording. Why should you silence "GL_DEPRICATION" but claim that the "CoreImage Kernel Language" is also? Yes, it's a "dialect" of GLSL. But still.

Someday you'll likely need to use Metal - just not this cycle.

One last thing - one major advantage of using Metal is that it will precompile your kernel code, and I believe it would have caught this kind of error in a build.

  • and? Here is for example the same shader written with both `CIColorKernel` and metal shader: https://habr.com/ru/company/otus/blog/681820/ but it doesn't explain how to use that metal shader. Could you please explain how to replace it with metal implementation now? – Gargo Dec 17 '22 at 15:24
  • CIColorKernel still works but it is indeed deprecated since it uses OpenGL. – Jeshua Lacock Jun 04 '23 at 06:14