Да, я знаю об использовании CIAreaAverate
CIFilter
для получения среднего цвета пикселей.
Я пытаюсь создать какую-то альтернативу, используя Accelerate Framework
, чтобы посмотреть, смогу ли я прийти с чем-то более быстрым.
Я отображаю CIImage
в контексте.Для этой цели у меня есть CIImage extension
...
let device: MTLDevice = MTLCreateSystemDefaultDevice()!
let context = CIContext.init(mtlDevice: device, options: [.workingColorSpace: kCFNull])
let w = self.extent.width
let h = self.extent.height
let size = w * h * 4
var bitmap = [UInt8](repeating: 0, count:Int(size))
context.render(self,
toBitmap: &bitmap,
rowBytes: 4 * Int(w),
bounds: self.extent,
format: .BGRA8,
colorSpace: nil)
На данный момент у меня есть bitmap
, содержащий чередующиеся байты BGRA.
Чтобы получить среднее значение R, G иБ, все, что мне нужно сделать, это что-то вроде этого:
var averageBlue : Int = 0
for x in stride(from:0, through: bitmap.count-4, by: 4) {
let value = bitmap[Int(x)]
averageBlue += Int(value)
}
averageBlue /= numberOfPixels
но этот цикл for
, как и ожидалось, медленен, как и ожидалось.
Я думал об использовании некоторого Accelerate
функция, подобная
vDSP_meanvD(bitmap, 2, &r, vDSP_Length(numberOfPixels))
, но для этой функции требуется bitmap
, чтобы быть массивом UnsafePointer<Double>
...
Я мог бы преобразовать bitmap
в это, но это потребовало бы for
петля, это медленно ...
Есть ли способ извлечь эти пиксели R, G и B и получить их индивидуальные средние значения, используя некоторые ускоряющие функции?