Home > front end >  What is the purpose of `contextWithCGContext:options:` method?
What is the purpose of `contextWithCGContext:options:` method?

Time:12-23

I treated CIContext as a kind of abstract state collector, which purpose is to allow CIFilters to function.

But there is [CIContext contextWithCGContext:options:] function which accepts CGContextRef as its input.

What does it mean? If this CGContextRef already contains some graphics, then how it will be used in newly created CIContext?

Will the contents of CGContextRef affect CIFilters in any way?

Is it possible to output CIImages, produced by CIFilters, into this initial CGContextRef?

CodePudding user response:

What does it mean? If this CGContextRef already contains some graphics, then how it will be used in newly created CIContext?

CIContext can be backed by the CGContext, and used to draw the filtered data on top of the context's content.

Is it possible to output CIImages, produced by CIFilters, into this initial CGContextRef?

(Almost) any UIView class sets a CGContext shortly before calling drawRect: method, and if you are not going to produce an UIImage/CIImage object, but instead just want to override this method and draw the result of your filters, you can get use of -[CIContext drawImage:inRect:fromRect:] in order to render your (e.g. filtered) data to the context of this view:

- (void)drawRect:(CGRect)rect {
    CIContext *context = [CIContext contextWithCGContext:UIGraphicsGetCurrentContext() options:nil];
    CIImage *input = self.image.CIImage;

    CIFilter *filter = [[self class] makeFilter];
    [filter setValue:input forKey:kCIInputImageKey];

    [context drawImage:filter.outputImage
                inRect:rect
              fromRect:filter.outputImage.extent];
}

Will the contents of CGContextRef affect CIFilters in any way?

Not exactly, CIFilters objects in isolation don't get affected by any side effects of CGContext state currently active. However if the CGContext itself has any transformation in place, it won't be discarded of course:

- (void)drawRect:(CGRect)rect {

    CGContextRef cgContext = UIGraphicsGetCurrentContext();
    CGContextRotateCTM(cgContext, radians(-45.));

    CIContext *context = [CIContext contextWithCGContext:cgContext options:nil];
    ... Applies CIFilter sequence ...
   
    // The result will be both filtered and rotated by 45 degrees counterclockwise
    [context drawImage:filter.outputImage
                inRect:rect
              fromRect:filter.outputImage.extent];
}
  • Related