Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I'm not aware of any accessible built-in way to convert a biplanar Y / CbCr image to RGB in iOS. However you should be able to perform the conversion yourself in software, e.g.</p> <pre><code>uint8_t clamp(int16_t input) { // clamp negative numbers to 0; assumes signed shifts // (a valid assumption on iOS) input &amp;= ~(num &gt;&gt; 16); // clamp numbers greater than 255 to 255; the accumulation // of the mask looks odd but is an attempt to avoid // pipeline stalls uint8_t saturationMask = num &gt;&gt; 8; saturationMask |= saturationMask &lt;&lt; 4; saturationMask |= saturationMask &lt;&lt; 2; saturationMask |= saturationMask &lt;&lt; 1; num |= saturationMask; return num&amp;0xff; } ... CVPixelBufferLockBaseAddress(imageBuffer, 0); size_t width = CVPixelBufferGetWidth(imageBuffer); size_t height = CVPixelBufferGetHeight(imageBuffer); uint8_t *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); CVPlanarPixelBufferInfo_YCbCrBiPlanar *bufferInfo = (CVPlanarPixelBufferInfo_YCbCrBiPlanar *)baseAddress; NSUInteger yOffset = EndianU32_BtoN(bufferInfo-&gt;componentInfoY.offset); NSUInteger yPitch = EndianU32_BtoN(bufferInfo-&gt;componentInfoY.rowBytes); NSUInteger cbCrOffset = EndianU32_BtoN(bufferInfo-&gt;componentInfoCbCr.offset); NSUInteger cbCrPitch = EndianU32_BtoN(bufferInfo-&gt;componentInfoCbCr.rowBytes); uint8_t *rgbBuffer = malloc(width * height * 3); uint8_t *yBuffer = baseAddress + yOffset; uint8_t *cbCrBuffer = baseAddress + cbCrOffset; for(int y = 0; y &lt; height; y++) { uint8_t *rgbBufferLine = &amp;rgbBuffer[y * width * 3]; uint8_t *yBufferLine = &amp;yBuffer[y * yPitch]; uint8_t *cbCrBufferLine = &amp;cbCrBuffer[(y &gt;&gt; 1) * cbCrPitch]; for(int x = 0; x &lt; width; x++) { // from ITU-R BT.601, rounded to integers uint8_t y = yBufferLine[x] - 16; uint8_t cb = cbCrBufferLine[x &amp; ~1] - 128; uint8_t cr = cbCrBufferLine[x | 1] - 128; uint8_t *rgbOutput = &amp;rgbBufferLine[x*3]; rgbOutput[0] = clamp(((298 * y + 409 * cr - 223) &gt;&gt; 8) - 223); rgbOutput[1] = clamp(((298 * y - 100 * cb - 208 * cr + 136) &gt;&gt; 8) + 136); rgbOutput[2] = clamp(((298 * y + 516 * cb - 277) &gt;&gt; 8) - 277); } } </code></pre> <p>Just written directly into this box and untested, I think I've got the cb/cr extraction correct. You'd then use <code>CGBitmapContextCreate</code> with <code>rgbBuffer</code> to create a <code>CGImage</code> and hence a <code>UIImage</code>.</p>
    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.
 

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