如果图像包含半透明像素,则可以轻松预处理以使所有 alpha 值低于某个阈值的像素完全透明,否则完全不透明。然后可以应用
CIAreaAverage
,就像在问题中最初建议的那样,最后通过将结果的 alpha 分量乘以图像大小来计算完全不透明像素的近似数量。
对于预处理,我们可以使用一个简单的 CIColorKernel,如下所示:
half4 clampAlpha(coreimage::sample_t color) {
half4 out = half4(color);
out.a = step(half(0.99), out.a);
return out;
}
(可以选择任何阈值,而不是0.99)
要从 CIAreaAverage
的输出中获取 alpha 组件,我们可以这样做:
let context = CIContext(options: [.workingColorSpace: NSNull(), .outputColorSpace: NSNull()])
var color: [Float] = [0, 0, 0, 0]
context.render(output,
toBitmap: &color,
rowBytes: MemoryLayout<Float>.size * 4,
bounds: CGRect(origin: .zero, size: CGSize(width: 1, height: 1)),
format: .RGBAf,
colorSpace: nil)
采用这种方法,所有操作都在GPU上完成,充分利用其固有的并行性。
顺便说一句,看看这个应用https://apps.apple.com/us/app/filter-magic/id1594986951。它可以让你玩转所有的CoreImage滤镜。