#画像のヒストグラムを作る
Swift5での画像のヒストグラムを作成する良いサンプルが無かったので覚書
公式サンプルに参考になるプロジェクトあり
Accelerate.vImageのvImageHistogramCalculation_ARGB8888を利用して計算するよう
https://developer.apple.com/documentation/accelerate/1545743-vimagehistogramcalculation_argb8
この方法では,カラーチャネルが1chでは計算できないが,ひとまず目的は達成したので良しとする
import Accelerate.vImage
func histogramCalculation(imageRef: CGImage) -> (red: [UInt], green: [UInt], blue: [UInt], alpha:[UInt])
{
let imgProvider: CGDataProvider = imageRef.dataProvider!
let imgBitmapData: CFData = imgProvider.data!
var imgBuffer = vImage_Buffer(
data: UnsafeMutableRawPointer(mutating: CFDataGetBytePtr(imgBitmapData)),
height: vImagePixelCount(imageRef.height),
width: vImagePixelCount(imageRef.width),
rowBytes: imageRef.bytesPerRow)
// bins: zero = red, green = one, blue = two, alpha = three
var histogramBinZero = [vImagePixelCount](repeating: 0, count: 256)
var histogramBinOne = [vImagePixelCount](repeating: 0, count: 256)
var histogramBinTwo = [vImagePixelCount](repeating: 0, count: 256)
var histogramBinThree = [vImagePixelCount](repeating: 0, count: 256)
histogramBinZero.withUnsafeMutableBufferPointer { zeroPtr in
histogramBinOne.withUnsafeMutableBufferPointer { onePtr in
histogramBinTwo.withUnsafeMutableBufferPointer { twoPtr in
histogramBinThree.withUnsafeMutableBufferPointer { threePtr in
var histogramBins = [zeroPtr.baseAddress, onePtr.baseAddress,
twoPtr.baseAddress, threePtr.baseAddress]
histogramBins.withUnsafeMutableBufferPointer { histogramBinsPtr in
let error = vImageHistogramCalculation_ARGB8888(&imgBuffer,
histogramBinsPtr.baseAddress!,
vImage_Flags(kvImageNoFlags))
guard error == kvImageNoError else {
fatalError("Error calculating histogram: \(error)")
}
}
}
}
}
}
return (histogramBinZero, histogramBinOne, histogramBinTwo, histogramBinThree)
}
iOSであれば,UIImageからcgImage作成は用意だが,macではNSImageなのでひと作業必要
var imageRect = NSRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
guard let cgImg1 = img.cgImage(forProposedRect: &imageRect, context: nil, hints: nil) else {
abort()
}
*func: load img, Time: 29.488ms
*func: make cgImg 1, Time: 0.069ms
*func: calc, Time: 162.501ms
*func: make 3ch chart, Time: 0.109ms
*func: draw, Time: 0.9739ms
十分な速度が出た
グラフはnsbezierPath curveを使うとなめらかになりそうだが
control point算出がめんどくさく,今回は直線でつないでいる
上記プロジェクトはGithubにおいておきます
ではまた