2013-06-13 2 views
3

Недавно я узнал, что метод renderinContext: игнорирует любые маски слоя. Я пытаюсь захватить видео экрана моего приложения, в котором я аниматирую путь маскированного CALayer.Использование renderInContext: для масок, созданных cgpaths

Чтобы записать экран, я использую класс ScreenCaptureView, найденный в Интернете. Представление берет «скриншот» его подвидных каждые х секунд и компилирует их в видео.

В методе drawRect я называю

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

После просмотра в Интернете, я нашел кого-то решение; однако он применяется для масок, которые являются изображениями. (Моя маска - 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]; 
} 

Можно ли сделать что-то подобное для масок из cgpaths?

ответ

0

Вы можете использовать CGContextClip() в renderInContext: клип на пути:

- (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 
} 
Смежные вопросы