我正在尝试在this site上实现示例以从相机中获取浮动图像,但我得到的输出图像仍然是UInt32像素(每个= 4 x UInt8颜色值)。
我无法弄清楚为什么不会发生转换为float32像素颜色分量的原因。所有我调整过的都是swift 2.0更新。
一起收集的示例代码:
let output = AVCaptureVideoDataOutput()
var settings = [kCVPixelBufferPixelFormatTypeKey as NSString:kCVPixelFormatType_32BGRA]
output.videoSettings = settings
output.alwaysDiscardsLateVideoFrames = true
func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!)
// Get Video Buffer
var imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
// Lock the base address of the pixel buffer
CVPixelBufferLockBaseAddress(imageBuffer, 0)
// Width and height
var width = CVPixelBufferGetWidth(imageBuffer);
var height = CVPixelBufferGetHeight(imageBuffer);
// Get the number of bytes per row for the pixel buffer
var bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)
// RGB Colorspace
var colorSpace = CGColorSpaceCreateDeviceRGB()
// The raw pointer to the buffer data
var baseAddress : UnsafeMutablePointer<Void> = CVPixelBufferGetBaseAddress(imageBuffer)
var baseAddressUint8 : UnsafeMutablePointer<UInt8> = UnsafeMutablePointer<UInt8>(baseAddress)
// The bitmap info for the buffer data, we have 32BGRA
//var bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue) | CGBitmapInfo.ByteOrder32Little
//I updated the previous to swift 2 with:
let bitmapInfo:CGBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue | CGBitmapInfo.ByteOrder32Little.rawValue)
let destBitmapInfo:CGBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue | CGBitmapInfo.FloatComponents.rawValue | CGBitmapInfo.ByteOrderDefault.rawValue)
// Create a bitmap graphics context with the sample buffer data
let context = CGBitmapContextCreate(baseAddressUint8, width, height, 8, bytesPerRow, colorSpace, bitmapInfo)
var sourceBuffer = vImage_Buffer(data:CGBitmapContextGetData(context), height:vImagePixelCount(height), width:vImagePixelCount(width), rowBytes:bytesPerRow)
var targetBufferPtr = UnsafeMutablePointer<Float>.alloc(width*height*4)
var targetBuffer = vImage_Buffer(data: targetBufferPtr!, height: vImagePixelCount(height), width: vImagePixelCount(width), rowBytes: width*16)
var srcFormat : vImage_CGImageFormat = vImage_CGImageFormat(
bitsPerComponent: UInt32(8),
bitsPerPixel: UInt32(32),
colorSpace: nil,
bitmapInfo: bitmapInfo,
version: UInt32(0),
decode: nil,
renderingIntent: CGColorRenderingIntent.RenderingIntentDefault
)
var destFormat : vImage_CGImageFormat = vImage_CGImageFormat(
bitsPerComponent: UInt32(32),
bitsPerPixel: UInt32(128),
colorSpace: nil,
bitmapInfo: destBitmapInfo,
version: UInt32(0),
decode: nil,
renderingIntent: CGColorRenderingIntent.RenderingIntentDefault
)
var err : vImage_Error = 0
var c = vImageConverter_CreateWithCGImageFormat(
&srcFormat,
&destFormat,
nil,
UInt32(kvImagePrintDiagnosticsToConsole),
&err)
err = vImageConvert_AnyToAny(
c.takeUnretainedValue(),
&sourceBuffer,
&targetBuffer,
nil,
UInt32(kvImagePrintDiagnosticsToConsole))
//My addition to get pixel values
let outImage = vImageCreateCGImageFromBuffer( &targetBuffer, &destFormat, nil, nil, vImage_Flags(kvImageNoFlags), &err )
let cameraImage = CIImage(CGImage: outImage.takeUnretainedValue())
let ctx = CIContext(options:nil)
let cgImage = ctx.createCGImage(cameraImage, fromRect:outputImage.extent)
let rawData:NSData = CGDataProviderCopyData(CGImageGetDataProvider(cgImage))!
let pixelcolors = UnsafePointer<Float32>(rawData.bytes)
let pixelcolors_pointer = UnsafeBufferPointer<Float32>(start:pixelcolors, count:4)
var BGRA_index = 0
for pixelcolor in UnsafeBufferPointer(start: pixelcolors_pointer.baseAddress, count: pixelcolors_pointer.count) {
if (pixelcolor.isNaN){break}
switch BGRA_index {
case 0:
bluemean = CGFloat (pixelcolor)
case 1:
greenmean = CGFloat (pixelcolor)
case 2:
redmean = CGFloat (pixelcolor)
case 3:
break
default:
break
}
BGRA_index += 1
}
}