我已经基于自定义内核创建了一个自定义CIFilter
,我无法使其正常工作,输出图像被黑色填充,我也不明白为什么。
这是着色器:
// MARK: Custom kernels
float4 eight_bit(sampler image, sampler palette_image, float paletteSize) {
float4 color = image.sample(image.coord());
float dist = distance(color, palette_image.sample(float2(0,0)));
float4 returnColor = palette_image.sample(float2(0,0));
for (int i = 1; i < floor(paletteSize); ++i) {
float tempDist = distance(color, palette_image.sample(float2(i,0)));
if (tempDist < dist) {
dist = tempDist;
returnColor = palette_image.sample(float2(i,0));
}
}
return returnColor;
}
第一个采样器是需要详细说明的图像,第二个图像是,并且该图像包含必须在该图像中使用的特定调色板的颜色。
调色板图像是根据RGBA
个值的数组创建的,并传递到使用此CIImage初始化程序Data
创建的init(bitmapData data: Data, bytesPerRow: Int, size: CGSize, format: CIFormat, colorSpace: CGColorSpace?)
缓冲区中。图像的高度为1px,颜色数为宽。图像正确获取,看起来像这样:
尝试检查我发现的着色器:
color
,则会得到原始图像,因此意味着采样器image
已正确传递palette_image
中的任何像素返回颜色,则滤镜产生的图像为黑色我开始认为palette_image
不能正确传递。图像如何通过过滤器传递:
override var outputImage: CIImage? {
guard let inputImage = inputImage else
{
return nil
}
let palette = EightBitColorFilter.palettes[Int(0)]
let paletteImage = EightBitColorFilter.image(from: palette)
let extent = inputImage.extent
let pixellateImage = inputImage.applyingFilter("CIPixellate", parameters: [kCIInputScaleKey: inputScale])
// let sampler = CISampler(image: paletteImage)
let arguments = [pixellateImage, paletteImage, Float(palette.count)] as [Any]
let final = kernel.apply(extent: extent, roiCallback: {
(index, rect) in
return rect
}, arguments: arguments)
return final
}
答案 0 :(得分:1)
您的采样坐标已关闭。
样品在Core Image中使用相对坐标,即(0,0)
对应于整个输入图像的左上角,(1,1)
对应于整个输入图像的右下角。
所以尝试这样的事情:
float4 eight_bit(sampler image, sampler palette_image, float paletteSize) {
float4 color = image.sample(image.coord());
// initial offset to land in the middle of the first pixel
float2 firstPaletteCoord = float2(1.0 / (2.0 * palletSize), 0.5);
float dist = distance(color, palette_image.sample(firstPaletteCoord));
float4 returnColor = palette_image.sample(firstPaletteCoord);
for (int i = 1; i < floor(paletteSize); ++i) {
// step one pixel further
float2 paletteCoord = firstPaletteCoord + float2(1.0 / paletteSize, 0.0);
float4 paletteColor = palette_image.sample(paletteCoord);
float tempDist = distance(color, paletteColor);
if (tempDist < dist) {
dist = tempDist;
returnColor = paletteColor;
}
}
return returnColor;
}