简体   繁体   English

使用renderInContext:用于由cgpaths创建的掩码

[英]Using renderInContext: for masks created by cgpaths

I recently found out that the renderinContext: method ignores any layer masks. 我最近发现renderinContext:方法忽略了任何图层蒙版。 I am trying to capture a video of my app's screen, in which I animate the path of a masked CALayer. 我正在尝试捕捉我的应用程序屏幕的视频,其中我为蒙面CALayer的路径设置动画。

To record the screen, I am using the ScreenCaptureView class, found online. 要记录屏幕,我使用的是在线发现的ScreenCaptureView类。 The view takes a "screenshot" of it's subviews every x seconds and compiles them into a video. 该视图每隔x秒对其子视图进行“屏幕截图”,并将其编译为视频。

In the drawRect method, I call drawRect方法中,我调用

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

After looking online, I found someone's solution; 在线查看后,我发现了某人的解决方案; however, it applies for masks that are images. 但是,它适用于作为图像的蒙版。 (My mask is a CGPath). (我的面具是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 *previewCapturedImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            return previewCapturedImage;
        }
}

//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];
}

Can I do something similar for masks from cgpaths? 我可以为cgpaths的面具做类似的事情吗?

You can use CGContextClip() in renderInContext: to clip to a path: 您可以在renderInContext:使用CGContextClip()来剪切到路径:

- (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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM