如何利用CGLayerRef离屏渲染实现图像遮罩?求Objective-C示例
使用CGLayerRef实现离屏渲染的图像遮罩(Objective-C)
我完全懂你找不到清晰示例的困扰——Core Graphics的文档确实有时候太偏理论了。下面是一个直接可用的Objective-C实现,用CGLayer做离屏渲染完成「形状遮罩图像」的需求,附带详细注释帮你理解每一步。
核心思路
CGLayer的优势就是离屏缓存高质量绘图内容,适合需要复用或者复杂绘制的场景。这里我们把遮罩和图像的合成操作放到CGLayer中完成,再将最终结果绘制到当前上下文,避免直接在主上下文操作带来的性能问题。
完整代码示例(UIView子类实现)
我们在UIView的drawRect:方法中完成绘制,这是Core Graphics绘图的标准入口:
#import <UIKit/UIKit.h> @interface MaskedImageView : UIView @end @implementation MaskedImageView - (void)drawRect:(CGRect)rect { // 1. 获取当前绘图上下文 CGContextRef currentContext = UIGraphicsGetCurrentContext(); // 2. 准备素材:替换成你自己的图像和遮罩尺寸 UIImage *sourceImage = [UIImage imageNamed:@"your_image_name"]; if (!sourceImage) { NSLog(@"图像加载失败,请检查图片名称"); return; } CGRect imageFrame = CGRectMake(0, 0, sourceImage.size.width, sourceImage.size.height); // 3. 创建CGLayer:参数分别是关联的主上下文、图层尺寸、附加属性(传NULL用默认) CGLayerRef offscreenLayer = CGLayerCreateWithContext(currentContext, sourceImage.size, NULL); CGContextRef layerContext = CGLayerGetContext(offscreenLayer); // -------------------------- // 方式1:用混合模式实现遮罩(推荐,更灵活) // -------------------------- // 先把原图绘制到离屏图层 CGContextDrawImage(layerContext, imageFrame, sourceImage.CGImage); // 设置混合模式为kCGBlendModeDestinationIn:只保留原图中与遮罩形状重叠的区域 CGContextSetBlendMode(layerContext, kCGBlendModeDestinationIn); // 绘制遮罩形状(这里示例是一个圆形,你可以替换成任意CGPath) CGContextAddEllipseInRect(layerContext, CGRectMake(40, 40, 180, 180)); CGContextSetFillColorWithColor(layerContext, [UIColor blackColor].CGColor); CGContextFillPath(layerContext); // -------------------------- // 方式2:用剪切路径实现遮罩(适合需要复杂路径剪切的场景) // -------------------------- /* // 先绘制遮罩路径并剪切上下文 CGContextAddEllipseInRect(layerContext, CGRectMake(40, 40, 180, 180)); CGContextClip(layerContext); // 再绘制原图,只会显示剪切区域内的部分 CGContextDrawImage(layerContext, imageFrame, sourceImage.CGImage); */ // 4. 将离屏图层的内容绘制到当前上下文 CGContextDrawLayerInRect(currentContext, imageFrame, offscreenLayer); // 5. 手动释放Core Graphics对象(ARC不会自动管理这些C类型对象) CGLayerRelease(offscreenLayer); } @end
关键细节解释
- CGLayer创建:
CGLayerCreateWithContext需要关联一个主上下文,这样图层的颜色空间等属性会和主上下文保持一致,避免颜色偏差。 - 混合模式
kCGBlendModeDestinationIn:这个模式的作用是:最终只保留目标(已经绘制的原图)中与源(遮罩形状)重叠的部分,遮罩形状的颜色不影响结果,只要是不透明的区域都会保留原图对应位置。 - 资源释放:Core Graphics的C类型对象(比如
CGLayerRef)不会被ARC自动管理,所以必须调用CGLayerRelease手动释放,避免内存泄漏。 - 遮罩形状替换:你可以把示例中的圆形替换成任意
CGPath,比如矩形、多边形甚至贝塞尔曲线转换的路径,只需要修改CGContextAddEllipseInRect这部分代码即可。
使用方法
把这个MaskedImageView类添加到你的项目中,在Storyboard或者代码中创建实例、设置好尺寸,就能看到遮罩后的效果了。
内容的提问来源于stack exchange,提问作者Reza.Ab
相关产品推荐
相关产品推荐

