baseAddress
è un puntatore mutevole sicure o più precisamente una UnsafeMutablePointer<Void>
. Si può facilmente accedere alla memoria una volta che avete convertito il puntatore lontano da Void
a un tipo più specifico:
// Convert the base address to a safe pointer of the appropriate type
let byteBuffer = UnsafeMutablePointer<UInt8>(baseAddress)
// read the data (returns value of type UInt8)
let firstByte = byteBuffer[0]
// write data
byteBuffer[3] = 90
Assicurarsi di utilizzare il tipo corretto (8, 16 o 32 bit unsigned int). Dipende dal formato video. Molto probabilmente è 8 bit.
Aggiornamento sui formati di buffer:
È possibile specificare il formato quando si inizializza l'istanza AVCaptureVideoDataOutput
. Hai sostanzialmente la scelta di:
- BGRA: un singolo piano dove i valori blu, verde, rosso e alfa sono memorizzati in un numero intero di 32 bit ciascuna
- 420YpCbCr8BiPlanarFullRange: Due aerei, il primo contenente un byte per ogni pixel con il valore Y (luma), il secondo contenente i valori Cb e Cr (chroma) per gruppi di pixel
- 420YpCbCr8BiPlanarVideoRange: lo stesso di 420YpCbCr8BiPlanarFullRange ma i valori Y sono ristretti all'intervallo 16 - 235 (per motivi storici)
Se ti interessano i valori dei colori e la velocità (o meglio la frequenza massima dei fotogrammi) non è un problema, quindi scegli il più semplice formato BGRA. Altrimenti, prendi uno dei formati video nativi più efficienti.
Se si dispone di due piani, è necessario ottenere l'indirizzo di base del piano desiderato (vedi esempio in formato video):
Formato video esempio
let pixelBuffer: CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)!
CVPixelBufferLockBaseAddress(pixelBuffer, 0)
let baseAddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0)
let bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0)
let byteBuffer = UnsafeMutablePointer<UInt8>(baseAddress)
// Get luma value for pixel (43, 17)
let luma = byteBuffer[17 * bytesPerRow + 43]
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)
BGRA esempio
let pixelBuffer: CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)!
CVPixelBufferLockBaseAddress(pixelBuffer, 0)
let baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer)
let int32PerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
let int32Buffer = UnsafeMutablePointer<UInt32>(baseAddress)
// Get BGRA value for pixel (43, 17)
let luma = int32Buffer[17 * int32PerRow + 43]
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)
Il buffer dei pixel del core video non contiene le informazioni su un singolo pixel, ma contiene le informazioni sui pixel di tutti i pixel catturati da una scena (una matrice bitmap di pixel). Vuoi dire che vuoi ottenere valori RGB per ogni pixel all'interno del buffer? –
Possibile duplicato di [Come convertire CVPixelBufferGetBaseAddress chiamata a Swift?] (Http://stackoverflow.com/questions/29814143/how-to-convert-cvpixelbuffergetbaseaddress-call-to-swift). –