Article

Building a Basic Conversion Workflow

Learn the fundamentals of the convert-any-to-any function by converting a CMYK image to an RGB image.

Overview

In summary, the steps for using the convert-any-to-any function are:

  1. Create either a vImage_CGImageFormat or a vImageCVImageFormat that describes the source image format.

  2. Create either a vImage_CGImageFormat or a vImageCVImageFormat that describes the destination image format.

  3. Create a converter based on the source and destination formats using vImageConverter_CreateWithCGImageFormat(_:_:_:_:_:), vImageConverter_CreateForCGToCVImageFormat(_:_:_:_:_:), or vImageConverter_CreateForCVToCGImageFormat(_:_:_:_:_:).

  4. Verify the number of source buffers matches the value returned by vImageConverter_GetNumberOfSourceBuffers(_:).

  5. Create and initialize the number of destination buffers specified by vImageConverter_GetNumberOfDestinationBuffers(_:).

  6. Call vImageConvert_AnyToAny(_:_:_:_:_:) to convert the source pixels to the destination image format and copy to the destination buffers.

The following code shows how to convert a 16-bit-per-channel CMYK image to an 8-bit-per-channel ARGB image using the steps described above.

// 1: Create a format that describes the source image.
var cmykSourceImageFormat = vImage_CGImageFormat(
    bitsPerComponent: 16,
    bitsPerPixel: 64,
    colorSpace: Unmanaged.passRetained(CGColorSpaceCreateDeviceCMYK()),
    bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue),
    version: 0,
    decode: nil,
    renderingIntent: .defaultIntent)

// 2: Create a format that describes the destination image.
var rgbDestinationImageFormat = vImage_CGImageFormat(
    bitsPerComponent: 8,
    bitsPerPixel: 32,
    colorSpace: nil,
    bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.first.rawValue),
    version: 0,
    decode: nil,
    renderingIntent: .defaultIntent)

// 3: Create a converter based on the source and destination formats.
let cmykToRgbUnmanagedConverter = vImageConverter_CreateWithCGImageFormat(
    &cmykSourceImageFormat,
    &rgbDestinationImageFormat,
    nil,
    vImage_Flags(kvImagePrintDiagnosticsToConsole),
    nil)

guard let cmykToRgbConverter = cmykToRgbUnmanagedConverter?.takeRetainedValue() else {
    return
}

// 4: Verify the number of source and destination buffers.
assert(vImageConverter_GetNumberOfSourceBuffers(cmykToRgbConverter) == 1,
       "Number of source buffers should be 1.")
assert(vImageConverter_GetNumberOfDestinationBuffers(cmykToRgbConverter) == 1,
       "Number of destination buffers should be 1.")

// 5: Create and initialize the destination buffer.
// Assumes `cmykSourceBuffer` exists and contains 16-bit-per-channel CMYK image data.
var rgbDestinationBuffer = vImage_Buffer()
vImageBuffer_Init(&rgbDestinationBuffer,
                  cmykSourceBuffer.height,
                  cmykSourceBuffer.width,
                  rgbDestinationImageFormat.bitsPerPixel,
                  vImage_Flags(kvImageNoFlags))

// 6: Call convert-any-to-any.
vImageConvert_AnyToAny(
    cmykToRgbConverter,
    &cmykSourceBuffer,
    &rgbDestinationBuffer,
    nil,
    vImage_Flags(kvImagePrintDiagnosticsToConsole))

See Also

Conversion Between Image Formats

Converting Color Images to Grayscale

Convert a color image to grayscale using matrix multiplication.

Standardizing Arbitrary Image Formats for Processing

Convert assets with disparate color spaces and bit depths to a standard working format for applying vImage operations.

Converting Luminance and Chrominance Planes to an ARGB Image

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

Conversion

Convert an image to a different format.