Проблема не в ограничении, а в коде вашего ядра.
Попробуйте это:
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 заключается в том, что он будет прекомпилировать код вашего ядра, и я считаю, что он смог бы обнаружить подобные ошибки в сборке.