Swift:Get Raw Histogram from CGImage

From Hawk Wiki
Jump to: navigation, search

Credit to http://stackoverflow.com/questions/27237297/how-to-get-meaningful-ciareahistogram-output

//dataImage is a CGImage
var imageData: CFDataRef = CGDataProviderCopyData(CGImageGetDataProvider(dataImage))
var dataInput: UnsafePointer<UInt8> = CFDataGetBytePtr(imageData)
//In swift, I have to do 2 steps. Not sure if there is any better way
var dataInputMutable = UnsafeMutablePointer<Void>(dataInput)
var height: vImagePixelCount = CGImageGetHeight(dataImage)
var width: vImagePixelCount = CGImageGetWidth(dataImage)
//Build a vImage_Buffer for next step
var vImageBuffer = vImage_Buffer(data: dataInputMutable, height: height, width: width, rowBytes: CGImageGetBytesPerRow(dataImage))
//Build the output array.
//To init a multi-dimensional UnsafeMutablePointer array. I have to do 3 steps
//First alloc sub arrays
var r = UnsafeMutablePointer<vImagePixelCount>.alloc(256)
var g = UnsafeMutablePointer<vImagePixelCount>.alloc(256)
var b = UnsafeMutablePointer<vImagePixelCount>.alloc(256)
var a = UnsafeMutablePointer<vImagePixelCount>.alloc(256)
//Then alloc main array
var histogram = UnsafeMutablePointer<UnsafeMutablePointer<vImagePixelCount>>.alloc(4)
//Set the pointer of sub arrays
histogram[0] = r
histogram[1] = g
histogram[2] = b
histogram[3] = a
//Finally, do the histogram calculation
var error:vImage_Error = vImageHistogramCalculation_ARGB8888(&vImageBuffer, histogram, 0);
        
if (error == kvImageNoError) {
    for var j = 0; j < 256; j++ {
        let currentVal = histogram[0][j] + histogram[1][j] + histogram[2][j] //I am making a grey histogram
        if currentVal > 0 {
            println("j=\(j),\(currentVal)")
        }
    }
    //delloc. MUST do this manually to prevent memory leak
    r.dealloc(256)
    g.dealloc(256)
    b.dealloc(256)
    a.dealloc(256)
    histogram.dealloc(4)
} else {
    println("Histogram vImage error: \(error)")
}