我的问题是我可以从 CVPixelBuffer 获取像素值,但所有值都是 255,255,255。 我使用的代码如下:
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
guard let photoPixelBuffer = photo.pixelBuffer else {
print("Error occurred while capturing photo: Missing pixel buffer (\(String(describing: error)))")
return
}
func pixelFrom(x: Int, y: Int, movieFrame: CVPixelBuffer) -> (UInt8, UInt8, UInt8) {
let baseAddress = CVPixelBufferGetBaseAddress(movieFrame)
let width = CVPixelBufferGetWidth(movieFrame)
let height = CVPixelBufferGetHeight(movieFrame)
let bytesPerRow = CVPixelBufferGetBytesPerRow(movieFrame)
let buffer = baseAddress!.assumingMemoryBound(to: UInt8.self)
let index = x+y*bytesPerRow
let b = buffer[index]
let g = buffer[index+1]
let r = buffer[index+2]
return (r, g, b)
}
print(pixelFrom(x:1,y:1,movieFrame:photoPixelBuffer))
all the r,g,b value is 255.
这取决于像素格式类型。
这是使用 Accelerate 框架从 CVImageBuffer 获取
kCVPixelFormatType_32BGRA
类型的 RBG“值”的示例。
import Foundation
import CoreVideo
import Accelerate
func convert(imageBuffer: CVImageBuffer) throws -> Rgb888ImageData {
guard CVPixelBufferGetPixelFormatType(imageBuffer) == kCVPixelFormatType_32BGRA else {
throw ConversionError.invalidPixelFormat
}
guard CVPixelBufferLockBaseAddress(imageBuffer, .readOnly) == kCVReturnSuccess else {
throw ConversionError.bufferLockError
}
defer {
CVPixelBufferUnlockBaseAddress(imageBuffer, .readOnly)
}
guard let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer) else {
throw ConversionError.invalidImageBuffer
}
let width = CVPixelBufferGetWidth(imageBuffer)
let height = CVPixelBufferGetHeight(imageBuffer)
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)
//Prepare 32BGRA source buffer
var srcBuffer = vImage_Buffer(data: baseAddress,
height: vImagePixelCount(height),
width: vImagePixelCount(width),
rowBytes: bytesPerRow)
//Prepare destination RGB data
let rgbBytesPerRow = width * 3
var rgbData = Data(count: height * rgbBytesPerRow)
let rawDestinationPtr = rgbData.withUnsafeMutableBytes{ $0.baseAddress }
guard let rawDestinationPtr = rawDestinationPtr else {
throw ConversionError.bufferLockError
}
var destBuffer = vImage_Buffer(data: rawDestinationPtr,
height: vImagePixelCount(height),
width: vImagePixelCount(width),
rowBytes: rgbBytesPerRow)
//Apply conversion BGRA -> RGB using Accelerate framework (CPU)
let error = vImageConvert_BGRA8888toRGB888(&srcBuffer, &destBuffer, vImage_Flags(kvImageNoFlags))
guard error == kvImageNoError else {
throw ConversionError.BGRA8888toRGB888Conversion
}
return Rgb888ImageData(rgbData: rgbData, imageWidth: width, imageHeight: height)
}