Uso renderInContext: para máscaras creadas por cgpaths

Recientemente descubrí que el método renderinContext: ignora cualquier máscara de capa. Estoy intentando capturar un video de la pantalla de mi aplicación, en el que animo el path de un CALayer enmascarado.

Para grabar la pantalla, estoy usando la class ScreenCaptureView , que se encuentra en línea. La vista toma una "captura de pantalla" de sus subidas cada x segundos y las comstack en un video.

En el método drawRect , llamo

 [[self.layer presentationLayer] renderInContext:context]; 

Después de mirar en línea, encontré la solución de alguien; sin embargo, se aplica a las máscaras que son imágenes. (Mi máscara es un CGPath).

 -(UIImage*) imageFromView:(UIView*)originalView { //Creating a fakeView which is initialized as our original view. //Actually i render images on a fakeView and take screenshot of this fakeView. UIView *fakeView = [[UIView alloc] initWithFrame:originalView.frame]; [fakeView.layer setMasksToBounds:originalView.layer.masksToBounds]; //Getting subviews of originalView. for (UIView *view in originalView.subviews) { //Getting screenshot of layer of view. UIGraphicsBeginImageContext(view.bounds.size); [view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *imageLayer = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); //If it is masked view, then get masked image. if (view.layer.mask) { //getting screenshot of masked layer. UIGraphicsBeginImageContext(view.bounds.size); [view.layer.mask renderInContext:UIGraphicsGetCurrentContext()]; //PNG Representation is most important. otherwise this masked image will not work. UIImage *maskedLayerImage=[UIImage imageWithData:UIImagePNGRepresentation(UIGraphicsGetImageFromCurrentImageContext())]; UIGraphicsEndImageContext(); //getting image by masking original image. imageLayer = [self maskImage:imageLayer withMask:maskedLayerImage]; } //If imageLayer is pointing to a valid object, then setting this image to UIImageView, our UIImageView frame having exactly as view.frame. if (imageLayer) { UIImageView *imageView = [[UIImageView alloc] initWithFrame:view.frame]; [imageView setImage:imageLayer]; [fakeView addSubview:imageView]; } } //At the end, taking screenshot of fakeView. This will get your Original Image. UIGraphicsBeginImageContext(fakeView.bounds.size); [fakeView.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *previewCaptunetworkingImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return previewCaptunetworkingImage; } } //Method is used to get masked image. - (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage { CGImageRef maskRef = maskImage.CGImage; CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef), CGImageGetHeight(maskRef), CGImageGetBitsPerComponent(maskRef), CGImageGetBitsPerPixel(maskRef), CGImageGetBytesPerRow(maskRef), CGImageGetDataProvider(maskRef), NULL, false); CGImageRef masked = CGImageCreateWithMask([image CGImage], mask); return [UIImage imageWithCGImage:masked]; } 

¿Puedo hacer algo similar para las máscaras de cgpaths?

Puede usar CGContextClip() en renderInContext: para recortar a una ruta:

 - (void)renderInContext:(CGContextRef)context { // Assign maskPath to whatever path you want to mask to (Here, it's assumed that your layer's mask is a CAShapeLayer) CGPathPathRef maskPath = [(CAShapeLayer *)self.mask path]; CGContextAddPath(context, maskPath); CGContextClip(context); // Do drawing code here }