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

如何高效将UIImage所有像素修改为指定单一颜色?

嘿,逐像素遍历这种操作真的是效率杀手,尤其是碰到尺寸大一点的图片,卡顿感直接拉满!我给你分享几个iOS开发里常用的高效实现方式,既能快速把整个图片改成指定颜色,还能完美保留原图片的透明度:

方案1:Core Graphics 直接绘制(兼容性最好)

Core Graphics是iOS底层的图形渲染框架,硬件加速加持,性能比逐像素高几个量级。核心思路是先铺满指定颜色,再用混合模式保留原图片的透明度:

func image(withSolidColor color: UIColor, from image: UIImage) -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
    defer { UIGraphicsEndImageContext() }
    
    // 先填充指定颜色到整个画布
    color.setFill()
    UIRectFill(CGRect(origin: .zero, size: image.size))
    
    // 用.destinationIn混合模式绘制原图,只保留原图的透明度信息
    image.draw(in: CGRect(origin: .zero, size: image.size), blendMode: .destinationIn, alpha: 1.0)
    
    return UIGraphicsGetImageFromCurrentImageContext()
}

这个方法能完美适配所有iOS版本,而且处理速度极快,是最通用的方案。

方案2:Core Image 滤镜实现(适合滤镜链式处理)

如果你的场景需要和其他滤镜(比如模糊、裁剪)配合使用,Core Image的滤镜链会更灵活,同样是硬件加速:

func image(withSolidColor color: UIColor, from image: UIImage) -> UIImage? {
    guard let ciImage = CIImage(image: image) else { return nil }
    
    // 创建纯色生成滤镜
    let colorGenerator = CIConstantColorGenerator()
    colorGenerator.color = CIColor(color: color)
    
    // 用混合滤镜将纯色与原图结合,保留原图透明度
    let compositeFilter = CISourceInCompositing()
    compositeFilter.inputImage = colorGenerator.outputImage
    compositeFilter.backgroundImage = ciImage
    
    guard let outputCIImage = compositeFilter.outputImage else { return nil }
    
    // 转换为UIImage,注意复用CIContext以提升性能
    let context = CIContext(options: [.useSoftwareRenderer: false])
    guard let cgImage = context.createCGImage(outputCIImage, from: ciImage.extent) else { return nil }
    
    return UIImage(cgImage: cgImage, scale: image.scale, orientation: image.imageOrientation)
}

注意:尽量全局复用同一个CIContext,避免重复创建带来的性能损耗。

方案3:UIGraphicsImageRenderer 简洁实现(iOS 10+ 推荐)

iOS 10之后推出的UIGraphicsImageRenderer封装了Core Graphics的上下文管理,代码更清爽,还自动适配屏幕缩放和 trait 环境:

func image(withSolidColor color: UIColor, from image: UIImage) -> UIImage? {
    let renderer = UIGraphicsImageRenderer(size: image.size, format: UIGraphicsImageRendererFormat(for: image.traitCollection))
    
    return renderer.image { context in
        color.setFill()
        context.fill(CGRect(origin: .zero, size: image.size))
        image.draw(in: CGRect(origin: .zero, size: image.size), blendMode: .destinationIn, alpha: 1.0)
    }
}

这个方案代码最简洁,适合iOS 10及以上的新项目,维护成本极低。

这几个方法的性能都远高于逐像素遍历,尤其是处理大图的时候差距特别明显,你可以根据自己的项目版本和需求选合适的~

内容的提问来源于stack exchange,提问作者user9469498

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:08:13