'init (source :)' был объявлен устаревшим в OS X 10.14: API ядра языка ядра образов устарел - PullRequest
0 голосов
/ 01 июня 2019

Я недавно обновился до Xcode 10.2, и мой код CIColorKernel больше не работает. Функция CIColorKernel возвращает ноль, и я получаю предупреждение - «init (source :)» устарел в OS X 10.14: устаревший API языка ядра образа.

Является ли Metal Shading Language единственной доступной альтернативой CIColorKernel? Похоже, MSL требует создания отдельного файла для пользовательского фильтра, и я хотел проверить, есть ли какие-либо лучшие варианты.

// 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])

1 Ответ

0 голосов
/ 19 июня 2019

Проблема не в ограничении, а в коде вашего ядра.

Попробуйте это:

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);" +
        "} " +
    "}"
)

Единственное, что я изменил, было (1) я переименовал Kernel в testKernel - не должно иметь значения - и изменил выражение if, чтобы проверять grayImage вместо s, как вы устанавливаете до подписи ядра. Это то второе изменение, которое имеет значение.

Способ, которым я создаю свое собственное ядро, состоит в том, чтобы поместить код в файл, зарегистрировать подкласс CIFilter для простоты использования, а затем выполнить это:

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

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

Обратите внимание на kernel! принудительное развертывание. Это означает, что когда я тестирую, мое приложение немедленно останавливает выполнение, потому что kernel равно нулю. То, как вы его кодируете, nil - правильное значение в том, как вы его объявляете.

Так вот, причина вы получили предупреждение, а я нет? Я все еще ориентируюсь на iOS 9+. (Я действительно обнаружил вашу проблему в тестовом проекте, где я обновляюсь до Metal и ориентируюсь на iOS 11+. Пока вы не ориентируетесь на iOS 12+, вы не получите предупреждение. Если вы посмотрите, как определяется CIColorFilter, вы найдете это:

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

Мне кажется, это плохая формулировка. Почему вы должны заставить замолчать «GL_DEPRICATION», но заявить, что «CoreImage Kernel Language» тоже? Да, это «диалект» GLSL. Но все же.

Когда-нибудь вам, вероятно, понадобится , чтобы использовать металл - только не этот цикл.

И последнее. Одно из главных преимуществ использования Metal заключается в том, что он будет прекомпилировать код вашего ядра, и я считаю, что он смог бы обнаружить подобные ошибки в сборке.

...