Core Graphics interoperability
Pass image data between the Core Graphics framework and the vImage library.
Overview
The vImage library uses the CGImage class as the main type to consume and produce still images. A CGImage instance may originate from NSImage or UIImage images, or from a CGContext drawing destination.
A typical Core Graphics-based vImage workflow consists of:
Selecting a source image, such as a Core Graphics-backed UIImage instance.
Initializing a vImage buffer from the image’s bitmap data.
Performing an operation on the vImage buffer, such as scaling or adjusting gamma.
Creating a destination image from the operation result with the same image format as the source image.
vImage provides the following functions that simplify interoperation with Core Graphics:
vImageBuffer_InitWithCGImage(_:_:_:_:_:) initializes a vImage buffer with the contents of a Core Graphics image.
vImageCreateCGImageFromBuffer(_:_:_:_:_:_:) creates a Core Graphics image from a vImage buffer.
The following code shows a passthrough function that accepts a CGImage image, populates a vImage buffer from the image, and generates a CGImage image from the buffer.
In this example, the call to vImageBuffer_InitWithCGImage(_:_:_:_:_:) populates the vImage_CGImageFormat and the vImage_Buffer variables with the properties of the source image:
static func passThrough(sourceImage: CGImage) -> CGImage? {
var format = vImage_CGImageFormat()
var buffer = vImage_Buffer()
defer {
buffer.free()
}
vImageBuffer_InitWithCGImage(
&buffer,
&format,
nil,
sourceImage,
vImage_Flags(kvImageNoFlags))
// Perform image-processing operations on `buffer`.
let destinationCGImage = vImageCreateCGImageFromBuffer(
&buffer,
&format,
nil,
nil,
vImage_Flags(kvImageNoFlags),
nil)
return destinationCGImage?.takeRetainedValue()
}Pass a fully initialized vImage_CGImageFormat to specify that vImageBuffer_InitWithCGImage(_:_:_:_:_:) converts the source CGImage image to the format that format describes. The following example converts the source image to a three-channel, 8-bit-per-channel RGB image:
static func passThrough(sourceImage: CGImage) -> CGImage? {
var format = vImage_CGImageFormat(
bitsPerComponent: 8,
bitsPerPixel: 8 * 3,
colorSpace: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue),
renderingIntent: .defaultIntent)!
var buffer = vImage_Buffer()
defer {
buffer.free()
}
vImageBuffer_InitWithCGImage(
&buffer,
&format,
nil,
sourceImage,
vImage_Flags(kvImageNoFlags))
// Perform image-processing operations on RGB888 `buffer`.
let destinationCGImage = vImageCreateCGImageFromBuffer(
&buffer,
&format,
nil,
nil,
vImage_Flags(kvImageNoFlags),
nil)
return destinationCGImage?.takeRetainedValue()
}