You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:41:09