Transfer image data between Core Video pixel buffers and vImage buffers to integrate vImage operations into a Core Image workflow
- iOS 11.2+
- Xcode 10.0+
vImage supports reading from and writing to Core Video pixel buffers. This sample implements a histogram equalization technique using vImage, then makes that technique accessible to Core Image workflows by sublassing
CIImage. An image processor kernel uses Core Video pixel buffers for input and output, so you must convert vImage buffers to and from
The example below shows an image before (on left) and after (on right) histogram equalization:
This sample walks you through the steps for reading from and writing to Core Video pixel buffers:
Defining an equalization image processor kernel.
Creating the source buffer.
Creating the destination buffer.
Applying the histogram equalization.
Writing the equalization result to the output.
Applying the equalization operation to an image.
Define an Equalization Image Processor Kernel
First, create the outline of your image processor kernel.
v structure that represents your image format; for example, an image that contains four 8-bit channels. The image processor kernel supports
k input and output formats. Override
format to return
k to match the
bitmap property of your format.
Equalization happens inside the processor kernel’s
process(with: function. The guard statement ensures that there is a valid input, and that both the input and output have a non-
nil Core Video pixel buffer.
This code shows the basic structure of your image processor kernel:
Create the Source Buffer
Create and populate the source vImage buffer with image data from the first input of the image processor kernel:
Create a description of the input pixel buffer format with
v. This function returns an unmanaged object reference, and
Image CVImage Format _Create With CVPixel Buffer(_:)
takereturns a managed
vinstance for use in step 3.
Image CVImage Format
Set the color space of the
Image CVImage Format
Initialize the source buffer and populate it with the image data from the input pixel buffer.
You’re responsible for releasing the buffer’s memory after you’re finished with it. To ensure that the buffer’s data is properly freed—even if the function exits early—the free function is deferred.
This code shows how to initialize the source buffer:
Create the Destination Buffer
Creating the destination buffer is similar to creating the source buffer, with one exception: You don’t initialize the destination with the contents of a pixel buffer. Rather, you use
v to allocate the correct amount of memory for the image dimensions and number of bits per pixel.
The following code shows how to initialize the destination buffer:
Apply Histogram Equalization
With the source and destination buffers initialized, you perform the histogram equalization operation. Equalization transforms an image so that it has a more uniform histogram, adding detail to low-contrast areas of an image.
Because your image processor kernel consumes and produces images consisting of four 8-bit channels, use the
v function. This function works equally well on all channel orderings; for example, RGBA or BGRA.
Write the Equalization Result to the Output
With the destination buffer populated with the equalization result, you’re ready to write the destination buffer’s contents to the output pixel buffer. The
v function copies the contents of a vImage pixel buffer to a Core Video pixel buffer.
Apply the Equalization Operation to an Image
apply(with method to generate a
CIImage instance based on the output of the processor’s
process(with: function. This code shows how you can display an image with a histogram equalization operation applied: