使用CGLayerRef和CGContextDrawLayerInRect

时间:2018-02-11 17:39:16

标签: ios objective-c uiimage core-graphics cgcontextref

我想在离屏渲染中使用CGLayerRef通过另一个图像遮罩图像,因为它适用于文档中提到的高质量渲染

  

核心图形图层绘图:   CGLayer对象允许您的应用程序使用图层进行绘制。   图层适用于以下内容:高质量的屏幕外渲染   您计划重复使用的绘图。

但我在objective-c中找不到任何我能理解其工作原理的例子。在我的背景下,我想要用形状图像(纯色形状)掩盖图像我曾经这样做过

//The context I use to mask my image with the mask image.
CGColorSpaceRef colorSpace= CGColorSpaceCreateDeviceRGB();
    CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, _bigImageRect.size.width, _bigImageRect.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);

//Mask image
CGContextClipToMask(mainViewContentContext,
                       CGRectMake(0,
                                   -_bigImageRect.origin.y,
                                   _bigImageRect.size.width,
                                   _bigImageRect.size.height),
                                   _maskImage.CGImage);

//Drawing the image on the mask image.
CGContextDrawImage(mainViewContentContext,
                       CGRectMake(0,
                                  0,
                                  _bigImageRect.size.width,
                                  _bigImageRect.size.height),
                                  _ImageToBeMasked.CGImage);

CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);
UIImage*maskedImage = [UIImage imageWithCGImage:mainViewContentBitmapContext];
CGImageRelease(mainViewContentBitmapContext)
return maskedImage;

但是如何使用CGLayers进行掩码如下?我感谢任何帮助。

CGLayerRef layer = CGLayerCreateWithContext(mainViewContentContext, _bigImageRect.size, NULL);
CGContextDrawLayerInRect(mainViewContentContext, _bigImageRect, layer);
CGLayerRelease(layer);
//And then.. how can I do the masking using this CGLayerRef???

2 个答案:

答案 0 :(得分:0)

我正式编写Swift代码,但是一旦我不得不处理掩码和CGLayer。

我通过以下步骤解决了问题:

  1. 画你的面具
  2. 将混合模式更改为CGBlendMode.sourceIn
  3. 画出你的颜色"图像。
  4. 这是有效的,因为CGBlendMode.sourceIn告诉上下文将源图像的alpha值与现有像素的颜色相乘。因此,面具的隐形部分(alpha = 0.0)将保持不可见。

    CGBlendMode的Apple文档:https://developer.apple.com/documentation/coregraphics/cgblendmode

答案 1 :(得分:0)

它并没有真正回答这个问题,但我终于使用了CGContextClipToMaskCGContextDrawImage这样的传统方法,但我设法获得了我想要的高质量掩蔽之前。再次,我需要提一下,这只适用于我的情况(它掩盖了一个图像,其上有一个渲染的bezier路径,但图像的全分辨率)如果您有相同的问题获取更多信息,您可以检查我的其他相关问题

Masking an image using bezierpath with image's full resolution

和我的github工作项目。

https://github.com/Reza-Abdolahi/HighResMasking

这里有适合我的代码:

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGImageRef maskImageRef = [_maskImage CGImage];
    CGContextRef myContext = CGBitmapContextCreate (NULL, _highResolutionImage.size.width, _highResolutionImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
    CGColorSpaceRelease(colorSpace);
    if (myContext==NULL)
        return NULL;

    CGFloat ratio = 0;
    ratio = _maskImage.size.width/ _highResolutionImage.size.width;
    if(ratio * _highResolutionImage.size.height < _maskImage.size.height) {
        ratio = _maskImage.size.height/ _highResolutionImage.size.height;
    }

    CGRect rectForMask  = {{0, 0}, {_maskImage.size.width, _maskImage.size.height}};
    CGRect rectForImageDrawing  = {{-((_highResolutionImage.size.width*ratio)-_maskImage.size.width)/2 , -((_highResolutionImage.size.height*ratio)-_maskImage.size.height)/2},
        {_highResolutionImage.size.width*ratio, _highResolutionImage.size.height*ratio}};

    CGContextClipToMask(myContext, rectForMask, maskImageRef);
    CGContextDrawImage(myContext, rectForImageDrawing, _highResolutionImage.CGImage);
    CGImageRef newImage = CGBitmapContextCreateImage(myContext);
    CGContextRelease(myContext);
    UIImage *theImage = [UIImage imageWithCGImage:newImage];
    CGImageRelease(newImage);
    return theImage;