CIImage 的平均颜色……更快的方法

Average color of a CIImage ... a faster method

我有一个 258x258 的 CIImage。我对其应用滤镜 CIAreaAverage,以获得该图像的平均颜色的绿色值。

我正在使用这个函数来获取...

// channel 0,1,2 = red, green, blue
func averageColorOfImage (_ inputImage: CIImage, _ channel: Int) -> Double {

  let extentVector = CIVector(x: inputImage.extent.origin.x, y: inputImage.extent.origin.y, z: inputImage.extent.size.width, w: inputImage.extent.size.height)

  guard let filter = CIFilter(name: "CIAreaAverage", parameters: [kCIInputImageKey: inputImage, kCIInputExtentKey: extentVector]) else { return 0 }
  guard let outputImage = Static.filter!.outputImage else { return 0 }

  var bitmap = [UInt8](repeating: 0, count: 4)
  let context = CIContext(options: [.workingColorSpace: kCFNull])
  context.render(outputImage, toBitmap: &bitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil)

  return Double(bitmap[channel]) / Double(255)
}

这运行速度相对较快,但我正在尝试查看是否有办法快速获得该颜色。

我记得 Core Image 有这个自定义 "core filter" 东西。

有没有办法使用自定义核心过滤器获取图像平均颜色的绿色值?

这就是我要做的。 (实际上在一个应用程序中创建特定大小的恒定颜色 CIImage。

(1) 使用 CIAreaAverage 获取您正在做的信号像素值。但不是使用绿色通道的输出来创建位图(我相信这是你面临的真正问题)....

(2) 使用 if 作为 CIConstantColorGenerator 的输入,这将创建 无限 大小的颜色。那么....

(3) 使用该输出作为 CICrop 的输入并将其裁剪为您想要的尺寸。

基本上,您最终会得到一个 "sized" CIImage,它具有您想要的任何颜色的恒定颜色。在下面的代码中,将 inputColor 的输入替换为 CIAreaAverage 的绿色通道输出,您将获得它的 640x640 CIImage。

func createNewPalette() {
    let filter = CIFilter(name: "CIConstantColorGenerator")
    filter?.setValue(CIColor(red: 0.7, green: 0.4, blue: 0.4), forKey: "inputColor")
    ciPalette = filter?.outputImage
    let crop = CIFilter(name: "CICrop")
    crop?.setValue(ciPalette, forKey: "inputImage")
    crop?.setValue(CIVector(x: 0, y: 0, z: 640, w: 640), forKey: "inputRectangle")
    ciPaletteOriginal = crop?.outputImage
}