【问题标题】:Average color of a CIImage ... a faster methodCIImage 的平均颜色...更快的方法
【发布时间】:2019-08-18 07:04:12
【问题描述】:

我有一个 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 有这个自定义的“核心过滤器”的东西。

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

【问题讨论】:

  • 几个想法,可能没有任何价值。 (1) 你到底想做什么?如果你想在UIImage 中渲染它,你能完全绕过 CI 吗? (2) 我从来没有用过CIAreaAverage,但是输出是一个像素。也许使用不同的方式来渲染你的位图? (3) 我认为您不想探索创建自定义CIKernel。它处理它的方式涉及(a)消除颜色内核,因为你想要“整个图像的平均值”,因此(b)一般内核意味着 - 我认为 - 你正在处理那个 image图像中每个像素的平均值。

标签: ios core-image cifilter


【解决方案1】:

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

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

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

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

基本上,您最终会得到一个“大小”的 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
}

【讨论】:

  • 不错的技巧,虽然它可以在一行中完成:return CIImage(color: CIColor(red: 0.7, green: 0.4, blue: 0.4)).cropped(to: CGRect(x: 0, y: 0, width: 640, height: 640)。但老实说,我不明白为什么这是在回答“如何更快地获得平均颜色?”问题...
猜你喜欢
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
  • 2020-11-13
  • 1970-01-01
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 2012-01-28
相关资源
最近更新 更多