---
title: Converting luminance and chrominance planes to an ARGB image
framework: accelerate
role: sampleCode
role_heading: Sample Code
path: accelerate/converting-luminance-and-chrominance-planes-to-an-argb-image
---

# Converting luminance and chrominance planes to an ARGB image

Create a displayable ARGB image using the luminance and chrominance information from your device’s camera.

## Overview

Overview As an alternative to the any-to-any conversion technique that Using vImage pixel buffers to generate video effects describes, vImage provides low-level functions for creating RGB images from the separate luminance and chrominance planes that an AVCaptureSession instance provides. These functions offer better performance and more granular configuration than using a vImageConverter instance. Configure the YpCbCr-to-ARGB information The vImageConvert_YpCbCrToARGB_GenerateConversion(_:_:_:_:_:_:) function generates the information that vImage requires to convert the luminance and chrominance planes to a single ARGB image. Video-range YpCbCr formats often don’t use very low and very high values. For example, an 8-bit video range format typically uses the range 16...235 for luminance and 16...240 for chrominance. The generate conversion function accepts a vImage_YpCbCrPixelRange structure that defines the pixel range. The following code example populates a vImage_YpCbCrToARGB structure with the required conversion information for video-range 8-bit pixels: var infoYpCbCrToARGB = vImage_YpCbCrToARGB()

func configureYpCbCrToARGBInfo() {     var pixelRange = vImage_YpCbCrPixelRange(Yp_bias: 16,                                              CbCr_bias: 128,                                              YpRangeMax: 235,                                              CbCrRangeMax: 240,                                              YpMax: 235,                                              YpMin: 16,                                              CbCrMax: 240,                                              CbCrMin: 16)

var ypCbCrToARGBMatrix = vImage_YpCbCrToARGBMatrix(Yp: 1.0,                                                        Cr_R: 1.402, Cr_G: -0.7141363,                                                        Cb_G: -0.3441363, Cb_B: 1.772)          _ = vImageConvert_YpCbCrToARGB_GenerateConversion(         &ypCbCrToARGBMatrix,         &pixelRange,         &infoYpCbCrToARGB,         kvImage422CbYpCrYp8,         kvImageARGB8888,         vImage_Flags(kvImageNoFlags)) } Lock the Core Video pixel buffer Before the sample app accesses the pixel data that AVFoundation supplies as a CVPixelBuffer, it calls CVPixelBufferLockBaseAddress(_:_:) to lock the pixel buffer and make the underlying memory available. After the YpCbCr-to-RGB conversion is complete, the code calls CVPixelBufferUnlockBaseAddress(_:_:) to unlock the pixel buffer. The convertYpCbCrToRGB(cvPixelBuffer:) function performs the YpCbCr-to-RGB conversion. CVPixelBufferLockBaseAddress(     pixelBuffer,     CVPixelBufferLockFlags.readOnly)

convertYpCbCrToRGB(cvPixelBuffer: pixelBuffer)

CVPixelBufferUnlockBaseAddress(     pixelBuffer,     CVPixelBufferLockFlags.readOnly) Create the source luminance and chrominance pixel buffers The convertYpCbCrToRGB(cvPixelBuffer:) function creates two pixel buffers that share memory with the CVPixelBuffer. The Core Video pixel buffer contains two planes: the plane at index 0 contains one channel that represents the luminance component, the plane at index 1 contains two interleaved channels that represent the two chrominance components. The init(referencing:planeIndex:overrideSize:pixelFormat:) function initializes a vImage.PixelBuffer that references a single plane of a multiple-plane Core Video pixel buffer. let lumaPixelBuffer = vImage.PixelBuffer(referencing: cvPixelBuffer,                                          planeIndex: 0,                                          pixelFormat: vImage.Planar8.self)

let chromaPixelBuffer = vImage.PixelBuffer(referencing: cvPixelBuffer,                                            planeIndex: 1,                                            pixelFormat: vImage.Interleaved8x2.self) Adjust the contrast of the image The sample app provides a Slider for changing the contrast of the final image. The following code example uses the tone-mapping technique that Adjusting saturation and applying tone mapping describes: if contrast != 1 {     lumaPixelBuffer.applyGamma(.halfPrecision(contrast),                                destination: lumaPixelBuffer) } Convert the YpCbCr image to an ARGB image The convert(lumaSource:chromaSource:conversionInfo:) converts the luminance and chrominance information in lumaPixelBuffer and chromaPixelBuffer to an ARGB image. This pixel buffer method calls the underlying vImage vImageConvert_420Yp8_CbCr8ToARGB8888(_:_:_:_:_:_:_:) function. argbPixelBuffer.convert(lumaSource: lumaPixelBuffer,                         chromaSource: chromaPixelBuffer,                         conversionInfo: infoYpCbCrToARGB)

## See Also

### Conversion Between Image Formats

- [Building a basic image conversion workflow](accelerate/building-a-basic-image-conversion-workflow.md)
- [Converting color images to grayscale](accelerate/converting-color-images-to-grayscale.md)
- [Applying color transforms to images with a multidimensional lookup table](accelerate/applying-color-transforms-to-images-with-a-multidimensional-lookup-table.md)
- [Building a basic image conversion workflow](accelerate/building-a-basic-image-conversion-workflow.md)
- [Conversion](accelerate/conversion.md)
