pub struct CIImageProcessorKernel { /* private fields */ }CIImageProcessor only.Expand description
The abstract class you extend to create custom image processors that can integrate with Core Image workflows.
Unlike the CIKernel class and its other subclasses that allow you to create new image-processing effects
with the Core Image Kernel Language, the CIImageProcessorKernel class provides direct access to the underlying
bitmap image data for a step in the Core Image processing pipeline. As such, you can create subclasses of this
class to integrate other image-processing technologies—such as Metal compute shaders, Metal Performance Shaders,
Accelerate vImage operations, or your own CPU-based image-processing routines—with a Core Image filter chain.
Your custom image processing operation is invoked by your subclassed image processor kernel’s
processWithInputs:arguments:output:error: method. The method can accept zero, one or more input objects.
Processors that generate imagery (such as a noise or pattern generator) need no inputs, while kernels that
composite source images together require multiple inputs. The arguments dictionary allows the caller to pass in
additional parameter values (such as the radius of a blur) and the output contains the destination for your
image processing code to write to.
The following code shows how you can subclass CIImageProcessorKernel to apply the Metal Performance Shader
<doc
://com.apple.documentation/documentation/metalperformanceshaders/mpsimagethresholdbinary> kernel to a CIImage:
class ThresholdImageProcessorKernel: CIImageProcessorKernel {
override class func process(with inputs: [CIImageProcessorInput]?, arguments: [String : Any]?, output: CIImageProcessorOutput) throws {
guard
let commandBuffer = output.metalCommandBuffer,
let input = inputs?.first,
let sourceTexture = input.metalTexture,
let destinationTexture = output.metalTexture,
let thresholdValue = arguments?["thresholdValue"] as? Float else {
return
}
let threshold = MPSImageThresholdBinary(
device: commandBuffer.device,
thresholdValue: thresholdValue,
maximumValue: 1.0,
linearGrayColorTransform: nil)
threshold.encode(
commandBuffer: commandBuffer,
sourceTexture: sourceTexture,
destinationTexture: destinationTexture)
}
}To apply to kernel to an image, the calling side invokes the image processor’s apply(withExtent:inputs:arguments:)
method. The following code generates a new CIImage object named result which contains a thresholded version of
the source image, inputImage.
let result = try? ThresholdImageProcessorKernel.apply(
withExtent: inputImage.extent,
inputs: [inputImage],
arguments: ["thresholdValue": 0.25])Important: Core Image will concatenate kernels in a render into as fewer programs as possible, avoiding the creation of intermediate buffers. However, it is unable to do this with image processor kernels. To get the best performance, you should use
CIImageProcessorKernelobjects only when your algorithms can’t be expressed as aCIKernel.
§Subclassing Notes
The CIImageProcessorKernel class is abstract; to create a custom image processor, you define a subclass of this class.
You do not directly create instances of a custom CIImageProcessorKernel subclass. Image processors must not carry or
use state specific to any single invocation of the processor, so all methods (and accessors for readonly properties)
of an image processor kernel class are class methods.
Your subclass should override at least the processWithInputs:arguments:output:error: method to perform its
image processing.
If your image processor needs to work with a larger or smaller region of interest in the input image than each
corresponding region of the output image (for example, a blur filter, which samples several input pixels for
each output pixel), you should also override the roiForInput:arguments:outputRect: method.
You can also override the formatForInputAtIndex: method and outputFormat property getter to customize the input and output pixel formats for your processor (for example, as part of a multi-step workflow where you extract a single channel from an RGBA image, apply an effect to that channel only, then recombine the channels).
§Using a Custom Image Processor
To apply your custom image processor class to create a CIImage object, call the
applyWithExtent:inputs:arguments:error: class method. (Do not override this method.)
See also Apple’s documentation
Implementations§
Source§impl CIImageProcessorKernel
impl CIImageProcessorKernel
Sourcepub unsafe fn processWithInputs_arguments_output_error(
inputs: Option<&NSArray<ProtocolObject<dyn CIImageProcessorInput>>>,
arguments: Option<&NSDictionary<NSString, AnyObject>>,
output: &ProtocolObject<dyn CIImageProcessorOutput>,
) -> Result<(), Retained<NSError>>
pub unsafe fn processWithInputs_arguments_output_error( inputs: Option<&NSArray<ProtocolObject<dyn CIImageProcessorInput>>>, arguments: Option<&NSDictionary<NSString, AnyObject>>, output: &ProtocolObject<dyn CIImageProcessorOutput>, ) -> Result<(), Retained<NSError>>
Override this class method to implement your Core Image Processor Kernel subclass.
When a CIImage containing your CIImageProcessorKernel class is rendered, your class’ implementation of
this method will be called as needed for that render. The method may be called more than once if Core Image
needs to tile to limit memory usage.
When your implementation of this class method is called, use the provided inputs and arguments objects
to return processed pixel data to Core Image via output.
Important: this is a class method so that you cannot use or capture any state by accident. All the parameters that affect the output results must be passed to
applyWithExtent:inputs:arguments:error:.
- Parameters:
- inputs: An array of `id <CIImageProcessorInput
that the class consumes to produce its output. Theinput.region` may be larger than the rect returned byroiForInput:arguments:outputRect:.
- arguments: the arguments dictionary that was passed to
applyWithExtent:inputs:arguments:error:. - output: The `id <CIImageProcessorOutput
that theCIImageProcessorKernel` must provide results to.
- error: Pointer to the
NSErrorobject into which processing errors will be written. - Returns: Returns YES if processing succeeded, and NO if processing failed.
§Safety
arguments generic should be of the correct type.
Sourcepub unsafe fn roiForInput_arguments_outputRect(
input_index: c_int,
arguments: Option<&NSDictionary<NSString, AnyObject>>,
output_rect: CGRect,
) -> CGRect
Available on crate feature objc2-core-foundation only.
pub unsafe fn roiForInput_arguments_outputRect( input_index: c_int, arguments: Option<&NSDictionary<NSString, AnyObject>>, output_rect: CGRect, ) -> CGRect
objc2-core-foundation only.Override this class method to implement your processor’s ROI callback.
This will be called one or more times per render to determine what portion of the input images are needed to render a given ‘outputRect’ of the output. This will not be called if processor has no input images.
The default implementation would return outputRect.
Important: this is a class method so that you cannot use or capture any state by accident. All the parameters that affect the output results must be passed to
applyWithExtent:inputs:arguments:error:.
- Parameters:
- inputIndex: the index that tells you which processor input for which to return the ROI rectangle.
- arguments: the arguments dictionary that was passed to
applyWithExtent:inputs:arguments:error:. - outputRect: the output
CGRectthat processor will be asked to output. - Returns:
The
CGRectof theinputIndexth input that is required for the aboveoutputRect
§Safety
arguments generic should be of the correct type.
Sourcepub unsafe fn roiTileArrayForInput_arguments_outputRect(
input_index: c_int,
arguments: Option<&NSDictionary<NSString, AnyObject>>,
output_rect: CGRect,
) -> Retained<NSArray<CIVector>>
Available on crate features CIVector and objc2-core-foundation only.
pub unsafe fn roiTileArrayForInput_arguments_outputRect( input_index: c_int, arguments: Option<&NSDictionary<NSString, AnyObject>>, output_rect: CGRect, ) -> Retained<NSArray<CIVector>>
CIVector and objc2-core-foundation only.Override this class method to implement your processor’s tiled ROI callback.
This will be called one or more times per render to determine what tiles
of the input images are needed to render a given outputRect of the output.
If the processor implements this method, then when rendered;
- as CoreImage prepares for a render, this method will be called for each input to return an ROI tile array.
- as CoreImage performs the render, the method
processWithInputs:arguments:output:error:will be called once for each tile.
Important: this is a class method so that you cannot use or capture any state by accident. All the parameters that affect the output results must be passed to
applyWithExtent:inputs:arguments:error:.
- Parameters:
- inputIndex: the index that tells you which processor input for which to return the array of ROI rectangles
- arguments: the arguments dictionary that was passed to
applyWithExtent:inputs:arguments:error:. - outputRect: the output
CGRectthat processor will be asked to output. - Returns:
An array of
CIVectorthat specify tile regions of theinputIndex’th input that is required for the aboveoutputRectEach region tile in the array is a created by calling/CIVector/vectorWithCGRect:/The tiles may overlap but should fully cover the area of ‘input’ that is needed. If a processor has multiple inputs, then each input should return the same number of region tiles.
§Safety
arguments generic should be of the correct type.
Sourcepub unsafe fn formatForInputAtIndex(input_index: c_int) -> CIFormat
Available on crate feature CIImage only.
pub unsafe fn formatForInputAtIndex(input_index: c_int) -> CIFormat
CIImage only.Override this class method if you want your any of the inputs to be in a specific pixel format.
The format must be one of kCIFormatBGRA8, kCIFormatRGBAh, kCIFormatRGBAf or kCIFormatR8.
On iOS 12 and macOS 10.14, the formats kCIFormatRh and kCIFormatRf are also supported.
If the requested inputFormat is 0, then the input will be a supported format that best
matches the rendering context’s /CIContext/workingFormat.
If a processor wants data in a colorspace other than the context’s working color space,
then call /CIImage/imageByColorMatchingWorkingSpaceToColorSpace: on the processor input.
If a processor wants it input as alpha-unpremultiplied RGBA data, then call
/CIImage/imageByUnpremultiplyingAlpha on the processor input.
Sourcepub unsafe fn outputFormat() -> CIFormat
Available on crate feature CIImage only.
pub unsafe fn outputFormat() -> CIFormat
CIImage only.Override this class property if you want your processor’s output to be in a specific pixel format.
The format must be one of kCIFormatBGRA8, kCIFormatRGBAh, kCIFormatRGBAf or kCIFormatR8.
On iOS 12 and macOS 10.14, the formats kCIFormatRh and kCIFormatRf are also supported.
If the outputFormat is 0, then the output will be a supported format that best
matches the rendering context’s /CIContext/workingFormat.
If a processor returns data in a color space other than the context working color space,
then call /CIImage/imageByColorMatchingColorSpaceToWorkingSpace: on the processor output.
If a processor returns data as alpha-unpremultiplied RGBA data, then call,
/CIImage/imageByPremultiplyingAlpha on the processor output.
Sourcepub unsafe fn outputIsOpaque() -> bool
pub unsafe fn outputIsOpaque() -> bool
Override this class property if your processor’s output stores 1.0 into the alpha channel of all pixels within the output extent.
If not overridden, false is returned.
Sourcepub unsafe fn synchronizeInputs() -> bool
pub unsafe fn synchronizeInputs() -> bool
Override this class property to return false if you want your processor to be given input objects that have not been synchronized for CPU access.
Generally, if your subclass uses the GPU your should override this method to return false. If not overridden, true is returned.
Sourcepub unsafe fn applyWithExtent_inputs_arguments_error(
extent: CGRect,
inputs: Option<&NSArray<CIImage>>,
arguments: Option<&NSDictionary<NSString, AnyObject>>,
) -> Result<Retained<CIImage>, Retained<NSError>>
Available on crate features CIImage and objc2-core-foundation only.
pub unsafe fn applyWithExtent_inputs_arguments_error( extent: CGRect, inputs: Option<&NSArray<CIImage>>, arguments: Option<&NSDictionary<NSString, AnyObject>>, ) -> Result<Retained<CIImage>, Retained<NSError>>
CIImage and objc2-core-foundation only.Call this method on your Core Image Processor Kernel subclass to create a new image of the specified extent.
The inputs and arguments will be retained so that your subclass can be called when the image is drawn.
This method will return nil and an error if:
- calling
outputFormaton your subclass returns an unsupported format. - calling
formatForInputAtIndex:on your subclass returns an unsupported format. - your subclass does not implement
processWithInputs:arguments:output:error:
- Parameters:
- extent: The bounding
CGRectof pixels that theCIImageProcessorKernelcan produce. This method will return/CIImage/emptyImageif extent is empty. - inputs: An array of
CIImageobjects to use as input. - arguments: This dictionary contains any additional parameters that the processor needs to
produce its output. The argument objects can be of any type but in order for
CoreImage to cache intermediates, they must be of the following immutable types:
NSArray,NSDictionary,NSNumber,NSValue,NSData,NSString,NSNull,CIVector,CIColor,CGImage,CGColorSpace, orMLModel. - error: Pointer to the
NSErrorobject into which processing errors will be written. - Returns:
An autoreleased
CIImage
§Safety
arguments generic should be of the correct type.
Source§impl CIImageProcessorKernel
Methods declared on superclass NSObject.
impl CIImageProcessorKernel
Methods declared on superclass NSObject.
Source§impl CIImageProcessorKernel
MultipleOutputSupport.
impl CIImageProcessorKernel
MultipleOutputSupport.
Sourcepub unsafe fn processWithInputs_arguments_outputs_error(
inputs: Option<&NSArray<ProtocolObject<dyn CIImageProcessorInput>>>,
arguments: Option<&NSDictionary<NSString, AnyObject>>,
outputs: &NSArray<ProtocolObject<dyn CIImageProcessorOutput>>,
) -> Result<(), Retained<NSError>>
pub unsafe fn processWithInputs_arguments_outputs_error( inputs: Option<&NSArray<ProtocolObject<dyn CIImageProcessorInput>>>, arguments: Option<&NSDictionary<NSString, AnyObject>>, outputs: &NSArray<ProtocolObject<dyn CIImageProcessorOutput>>, ) -> Result<(), Retained<NSError>>
Override this class method of your Core Image Processor Kernel subclass if it needs to produce multiple outputs.
This supports 0, 1, 2 or more input images and 2 or more output images.
When a CIImage containing your CIImageProcessorKernel class is rendered, your class’ implementation of
this method will be called as needed for that render. The method may be called more than once if Core Image
needs to tile to limit memory usage.
When your implementation of this class method is called, use the provided inputs and arguments objects
to return processed pixel data to Core Image via multiple outputs.
Important: this is a class method so that you cannot use or capture any state by accident. All the parameters that affect the output results must be passed to
applyWithExtent:inputs:arguments:error:.
- Parameters:
- inputs: An array of `id <CIImageProcessorInput
that the class consumes to produce its output. Theinput.region` may be larger than the rect returned byroiForInput:arguments:outputRect:.
- arguments: the arguments dictionary that was passed to
applyWithExtent:inputs:arguments:error:. - outputs: An array `id <CIImageProcessorOutput
that theCIImageProcessorKernel` must provide results to.
- error: Pointer to the
NSErrorobject into which processing errors will be written. - Returns: Returns YES if processing succeeded, and NO if processing failed.
§Safety
arguments generic should be of the correct type.
Sourcepub unsafe fn outputFormatAtIndex_arguments(
output_index: c_int,
arguments: Option<&NSDictionary<NSString, AnyObject>>,
) -> CIFormat
Available on crate feature CIImage only.
pub unsafe fn outputFormatAtIndex_arguments( output_index: c_int, arguments: Option<&NSDictionary<NSString, AnyObject>>, ) -> CIFormat
CIImage only.Override this class method if your processor has more than one output and
you want your processor’s output to be in a specific supported CIPixelFormat.
The format must be one of kCIFormatBGRA8, kCIFormatRGBAh, kCIFormatRGBAf or kCIFormatR8.
On iOS 12 and macOS 10.14, the formats kCIFormatRh and kCIFormatRf are also supported.
If the outputFormat is 0, then the output will be a supported format that best
matches the rendering context’s /CIContext/workingFormat.
- Parameters:
- outputIndex: the index that tells you which processor output for which to return the desired
CIPixelFormat - arguments: the arguments dictionary that was passed to
applyWithExtent:inputs:arguments:error:. - Returns:
Return the desired
CIPixelFormat
§Safety
arguments generic should be of the correct type.
Sourcepub unsafe fn applyWithExtents_inputs_arguments_error(
extents: &NSArray<CIVector>,
inputs: Option<&NSArray<CIImage>>,
arguments: Option<&NSDictionary<NSString, AnyObject>>,
) -> Result<Retained<NSArray<CIImage>>, Retained<NSError>>
Available on crate features CIImage and CIVector only.
pub unsafe fn applyWithExtents_inputs_arguments_error( extents: &NSArray<CIVector>, inputs: Option<&NSArray<CIImage>>, arguments: Option<&NSDictionary<NSString, AnyObject>>, ) -> Result<Retained<NSArray<CIImage>>, Retained<NSError>>
CIImage and CIVector only.Call this method on your multiple-output Core Image Processor Kernel subclass to create an array of new image objects given the specified array of extents.
The inputs and arguments will be retained so that your subclass can be called when the image is drawn.
This method will return nil and an error if:
- calling
outputFormatAtIndex:arguments:on your subclass returns an unsupported format. - calling
formatForInputAtIndex:on your subclass returns an unsupported format. - your subclass does not implement
processWithInputs:arguments:output:error:
- Parameters:
- extents: The array of bounding rectangles that the
CIImageProcessorKernelcan produce. Each rectangle in the array is an object created using/CIVector/vectorWithCGRect:This method will returnCIImage.emptyImageif a rectangle in the array is empty. - inputs: An array of
CIImageobjects to use as input. - arguments: This dictionary contains any additional parameters that the processor needs to
produce its output. The argument objects can be of any type but in order for
CoreImage to cache intermediates, they must be of the following immutable types:
NSArray,NSDictionary,NSNumber,NSValue,NSData,NSString,NSNull,CIVector,CIColor,CGImage,CGColorSpace, orMLModel. - error: Pointer to the
NSErrorobject into which processing errors will be written. - Returns:
An autoreleased
CIImage
§Safety
arguments generic should be of the correct type.
Methods from Deref<Target = NSObject>§
Sourcepub fn doesNotRecognizeSelector(&self, sel: Sel) -> !
pub fn doesNotRecognizeSelector(&self, sel: Sel) -> !
Handle messages the object doesn’t recognize.
See Apple’s documentation for details.
Methods from Deref<Target = AnyObject>§
Sourcepub fn class(&self) -> &'static AnyClass
pub fn class(&self) -> &'static AnyClass
Dynamically find the class of this object.
§Panics
May panic if the object is invalid (which may be the case for objects
returned from unavailable init/new methods).
§Example
Check that an instance of NSObject has the precise class NSObject.
use objc2::ClassType;
use objc2::runtime::NSObject;
let obj = NSObject::new();
assert_eq!(obj.class(), NSObject::class());Sourcepub unsafe fn get_ivar<T>(&self, name: &str) -> &Twhere
T: Encode,
👎Deprecated: this is difficult to use correctly, use Ivar::load instead.
pub unsafe fn get_ivar<T>(&self, name: &str) -> &Twhere
T: Encode,
Ivar::load instead.Use Ivar::load instead.
§Safety
The object must have an instance variable with the given name, and it
must be of type T.
See Ivar::load_ptr for details surrounding this.
Sourcepub fn downcast_ref<T>(&self) -> Option<&T>where
T: DowncastTarget,
pub fn downcast_ref<T>(&self) -> Option<&T>where
T: DowncastTarget,
Attempt to downcast the object to a class of type T.
This is the reference-variant. Use Retained::downcast if you want
to convert a retained object to another type.
§Mutable classes
Some classes have immutable and mutable variants, such as NSString
and NSMutableString.
When some Objective-C API signature says it gives you an immutable class, it generally expects you to not mutate that, even though it may technically be mutable “under the hood”.
So using this method to convert a NSString to a NSMutableString,
while not unsound, is generally frowned upon unless you created the
string yourself, or the API explicitly documents the string to be
mutable.
See Apple’s documentation on mutability and on
isKindOfClass: for more details.
§Generic classes
Objective-C generics are called “lightweight generics”, and that’s because they aren’t exposed in the runtime. This makes it impossible to safely downcast to generic collections, so this is disallowed by this method.
You can, however, safely downcast to generic collections where all the
type-parameters are AnyObject.
§Panics
This works internally by calling isKindOfClass:. That means that the
object must have the instance method of that name, and an exception
will be thrown (if CoreFoundation is linked) or the process will abort
if that is not the case. In the vast majority of cases, you don’t need
to worry about this, since both root objects NSObject and
NSProxy implement this method.
§Examples
Cast an NSString back and forth from NSObject.
use objc2::rc::Retained;
use objc2_foundation::{NSObject, NSString};
let obj: Retained<NSObject> = NSString::new().into_super();
let string = obj.downcast_ref::<NSString>().unwrap();
// Or with `downcast`, if we do not need the object afterwards
let string = obj.downcast::<NSString>().unwrap();Try (and fail) to cast an NSObject to an NSString.
use objc2_foundation::{NSObject, NSString};
let obj = NSObject::new();
assert!(obj.downcast_ref::<NSString>().is_none());Try to cast to an array of strings.
use objc2_foundation::{NSArray, NSObject, NSString};
let arr = NSArray::from_retained_slice(&[NSObject::new()]);
// This is invalid and doesn't type check.
let arr = arr.downcast_ref::<NSArray<NSString>>();This fails to compile, since it would require enumerating over the array to ensure that each element is of the desired type, which is a performance pitfall.
Downcast when processing each element instead.
use objc2_foundation::{NSArray, NSObject, NSString};
let arr = NSArray::from_retained_slice(&[NSObject::new()]);
for elem in arr {
if let Some(data) = elem.downcast_ref::<NSString>() {
// handle `data`
}
}Trait Implementations§
Source§impl AsRef<AnyObject> for CIImageProcessorKernel
impl AsRef<AnyObject> for CIImageProcessorKernel
Source§impl AsRef<NSObject> for CIImageProcessorKernel
impl AsRef<NSObject> for CIImageProcessorKernel
Source§impl Borrow<AnyObject> for CIImageProcessorKernel
impl Borrow<AnyObject> for CIImageProcessorKernel
Source§impl Borrow<NSObject> for CIImageProcessorKernel
impl Borrow<NSObject> for CIImageProcessorKernel
Source§impl ClassType for CIImageProcessorKernel
impl ClassType for CIImageProcessorKernel
Source§const NAME: &'static str = "CIImageProcessorKernel"
const NAME: &'static str = "CIImageProcessorKernel"
Source§type ThreadKind = <<CIImageProcessorKernel as ClassType>::Super as ClassType>::ThreadKind
type ThreadKind = <<CIImageProcessorKernel as ClassType>::Super as ClassType>::ThreadKind
Source§impl Debug for CIImageProcessorKernel
impl Debug for CIImageProcessorKernel
Source§impl Deref for CIImageProcessorKernel
impl Deref for CIImageProcessorKernel
Source§impl Hash for CIImageProcessorKernel
impl Hash for CIImageProcessorKernel
Source§impl Message for CIImageProcessorKernel
impl Message for CIImageProcessorKernel
Source§impl NSObjectProtocol for CIImageProcessorKernel
impl NSObjectProtocol for CIImageProcessorKernel
Source§fn isEqual(&self, other: Option<&AnyObject>) -> bool
fn isEqual(&self, other: Option<&AnyObject>) -> bool
Source§fn hash(&self) -> usize
fn hash(&self) -> usize
Source§fn isKindOfClass(&self, cls: &AnyClass) -> bool
fn isKindOfClass(&self, cls: &AnyClass) -> bool
Source§fn is_kind_of<T>(&self) -> bool
fn is_kind_of<T>(&self) -> bool
isKindOfClass directly, or cast your objects with AnyObject::downcast_ref