我一直在努力弄清楚如何执行从源图像到另一幅图像的颜色转移。
我要创建的过滤器需要2个大小完全相同的图像( ImageA 和 ImageB )。过滤器生成的输出图像会将颜色的所有像素从 imageA 更改为 imageB 的相同像素位置处的颜色。
检查图像。我需要使用 ImageA 作为源并将 ImageB 作为一种 color mask ,将蓝色像素更改为绿色和紫色像素。如您所见,只有与绿色和紫色重叠的蓝色区域已更改(将灰色视为透明...)
我的问题是: 1)这可行吗? 2)我应该使用通用内核吗?从我的理解来看,颜色内核也应该起作用,但是我不确定是否可以将2张图像传递给颜色内核。
您能提供一个内核代码示例吗?
在每个像素上执行的非常简单的非优化伪代码可能类似于:
color func (source imageA, source imageB, color colorToChange) {
if imageA.currentpixel.color == colorToChange{
if imageB.getPixel(imageA.currentPixel).color not transparent{
return imageB.getPixel(imageA.currentPixel).color
}
}
return imageA.currentPixel.color
}
这是我正在使用的当前过滤器(虽然我正在获得奇怪的结果)
kernel vec4 coreImageKernel(sampler image, sampler msk, __color color)
{
vec4 a = sample(image, samplerCoord(image));
if (length(a - color) == 0.0){
return sample(msk, samplerCoord(msk));
}else{
return a;
}
}
答案 0 :(得分:2)
可以使用CIKernel
,但是我不相信使用简单的CIColorKernel
,因为您需要使用两个CIImages
。
这仍然是非常简单的代码。您需要三个输入,在您的示例中为“ IMAGE A”,“ IMAGE B”,并且图像B的像素颜色为 ignore 。由于CoreImage可以逐像素工作,因此您只需要处理两个图像中的当前像素即可。
基本代码如下:
kernel vec4 createResult(sampler imageA, sampler imageB, vec4 backgroundColor) {
vec4 pixelA = sample(imageA, samplerCoord(imageA));
vec4 pixelB = sample(imageB, samplerCoord(imageB));
if (pixelA == backgroundColor) {
return pixelA;
} else if (pixelB == backgroundColor) {
return pixelA;
} else {
return pixelB;
}
}
这是未经测试的内核代码,因此可能存在语法错误。但这是逻辑:
请注意,只有两个 像素都不是背景色时,子弹#4才能到达。
最后一点-苹果决定弃用OpenGL。在WWDC '18之后,我花了一个星期的时间将内核代码更改为Metal 2代码,但尚未成功。颜色核?简单。但是,既有扭曲内核又有普通内核的东西……与获取周围像素有关的东西仍然让我难以理解。我 认为这与我编写samplerTransform
的方式有关,但是还没有时间来完成它。
您应该将其用作“基于金属的”内核是很好的,因为我确实复制了一个简单的传递作为CIKernel。请注意!