Average color of a CIImage … a faster method

天涯浪子 提交于 2019-12-08 03:30:40

问题


I have a CIImage that is 258x258. I apply a filter CIAreaAverage to it, in order to get the green value of the average color of that image.

I am using this function to get that...

// 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)
}

This runs relatively fast but I am trying to see if there is a way to get that color fast.

I remember that Core Image has this custom "core filter" stuff.

Is there a way to do get the green value of the average color of an image using custom core filter?


回答1:


Here's what I'd do. (And actually do in one app to create a constant color CIImage of a specific size.

(1) Use CIAreaAverage to get you signal pixel value just like you are doing. But instead of using the output of the green channel to create a bitmap (which I believe is the real issue you are facing)....

(2) Use if as input for CIConstantColorGenerator, which will create an infinite sized color. Then....

(3) Use that output as input to CICrop and crop it to the dimensions you want.

Essentially you end up with a "sized" CIImage of a constant color of whatever you wish. In the code below, replace my input for inputColor with the green channel output of CIAreaAverage and you'll get a 640x640 CIImage of it.

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
}


来源:https://stackoverflow.com/questions/54818120/average-color-of-a-ciimage-a-faster-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!