Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you only need the luminance channel, I recommend against using BGRA format, as it comes with a conversion overhead. Apple suggest using BGRA if you're doing rendering stuff, but you don't need it for extracting the luminance information. As Brad already mentioned, the most efficient format is the camera-native YUV format.</p> <p>However, extracting the right bytes from the sample buffer is a bit tricky, especially regarding the iPhone 3G with it's interleaved YUV 422 format. So here is my code, which works fine with the iPhone 3G, 3GS, iPod Touch 4 and iPhone 4S.</p> <pre><code>#pragma mark - #pragma mark AVCaptureVideoDataOutputSampleBufferDelegate Methods #if !(TARGET_IPHONE_SIMULATOR) - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection; { // get image buffer reference CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); // extract needed informations from image buffer CVPixelBufferLockBaseAddress(imageBuffer, 0); size_t bufferSize = CVPixelBufferGetDataSize(imageBuffer); void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); CGSize resolution = CGSizeMake(CVPixelBufferGetWidth(imageBuffer), CVPixelBufferGetHeight(imageBuffer)); // variables for grayscaleBuffer void *grayscaleBuffer = 0; size_t grayscaleBufferSize = 0; // the pixelFormat differs between iPhone 3G and later models OSType pixelFormat = CVPixelBufferGetPixelFormatType(imageBuffer); if (pixelFormat == '2vuy') { // iPhone 3G // kCVPixelFormatType_422YpCbCr8 = '2vuy', /* Component Y'CbCr 8-bit 4:2:2, ordered Cb Y'0 Cr Y'1 */ // copy every second byte (luminance bytes form Y-channel) to new buffer grayscaleBufferSize = bufferSize/2; grayscaleBuffer = malloc(grayscaleBufferSize); if (grayscaleBuffer == NULL) { NSLog(@"ERROR in %@:%@:%d: couldn't allocate memory for grayscaleBuffer!", NSStringFromClass([self class]), NSStringFromSelector(_cmd), __LINE__); return nil; } memset(grayscaleBuffer, 0, grayscaleBufferSize); void *sourceMemPos = baseAddress + 1; void *destinationMemPos = grayscaleBuffer; void *destinationEnd = grayscaleBuffer + grayscaleBufferSize; while (destinationMemPos &lt;= destinationEnd) { memcpy(destinationMemPos, sourceMemPos, 1); destinationMemPos += 1; sourceMemPos += 2; } } if (pixelFormat == '420v' || pixelFormat == '420f') { // kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange = '420v', // kCVPixelFormatType_420YpCbCr8BiPlanarFullRange = '420f', // Bi-Planar Component Y'CbCr 8-bit 4:2:0, video-range (luma=[16,235] chroma=[16,240]). // Bi-Planar Component Y'CbCr 8-bit 4:2:0, full-range (luma=[0,255] chroma=[1,255]). // baseAddress points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct // i.e.: Y-channel in this format is in the first third of the buffer! int bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0); baseAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer,0); grayscaleBufferSize = resolution.height * bytesPerRow ; grayscaleBuffer = malloc(grayscaleBufferSize); if (grayscaleBuffer == NULL) { NSLog(@"ERROR in %@:%@:%d: couldn't allocate memory for grayscaleBuffer!", NSStringFromClass([self class]), NSStringFromSelector(_cmd), __LINE__); return nil; } memset(grayscaleBuffer, 0, grayscaleBufferSize); memcpy (grayscaleBuffer, baseAddress, grayscaleBufferSize); } // do whatever you want with the grayscale buffer ... // clean-up free(grayscaleBuffer); } #endif </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload