CGColor 和 CGColorSpace:什么是它们,颜色模型以及如何管理它们

作者: IT Sectr 发布日期: 2026-07-21 阅读时间: 9 分钟

Core Graphics 中的颜色处理围绕着两个相互关联的实体构建——CGColor 和 CGColorSpace。CGColor 表示带有组件的具体颜色,而 CGColorSpace 定义了这些组件的解释模型。根据 Apple Documentation (2026),Core Graphics 支持 20 多种标准色彩空间,包括 sRGB、Generic Gray 和 Generic CMYK。理解 CGColor 和 CGColorSpace 之间的区别对于在 iOS 和 macOS 上正确绘制图形是必要的。

要点

  • CGColor — 存储颜色组件和色彩空间引用的对象
  • CGColorSpace — 定义颜色组件解释模型(RGB、Gray、CMYK)的对象
  • 每个 CGColor 恰好与一个 CGColorSpace 相关联——没有空间的颜色被视为不完整
  • Core Graphics 提供基于 ICC 的色彩管理,用于在设备之间进行准确的色彩再现
  • 色彩空间之间的转换通过 macOS 上的 ColorSync 和 iOS 上的 Quartz Core 执行

什么是 CGColor 和 CGColorSpace?

CGColor — 是 Core Graphics 中表示颜色的基本对象。在 CGColor 结构中存储了颜色组件的数值和对 CGColorSpace 的引用——解释这些组件的色彩空间。如果没有绑定到色彩空间,组件的数值就没有意义:在 RGB 中值 (1.0, 0.0, 0.0) 是红色,但在 CMYK 中是青色。

CGColorSpace — 是定义颜色模型和可表示值范围(色域)的对象。色彩空间规定了数值组件在特定输出设备上转换为可见颜色的规则。Core Graphics 既支持标准的 ICC 配置文件空间,也支持通过带有自定义转换表的 CGColorSpace 创建的自定义空间。

颜色和色彩空间分离的架构——Core Graphics 的关键特性,使其区别于颜色存储为简单数字集合的 API。这种方法允许 Core Graphics 执行独立于硬件的色彩管理:同一个 CGColor 对象可以通过 CGColorSpace 配置文件自动转换组件,从而在不同的显示器上正确显示。

Core Graphics 中的颜色如何工作

Core Graphics 通过基于 ICC 配置文件(International Color Consortium)的模型来实现颜色。每个 CGColorSpace 包含对 ICC 配置文件的引用——颜色组件如何转换为 CIE XYZ(独立于硬件的色彩空间)的标准化描述。这使得 Core Graphics 能够在不同显示器之间执行自动色度补偿。

CGColor 对象的生命周期

当通过 CGColorCreate 函数创建 CGColor 时,会从传递的数组中获取组件并绑定到指定的 CGColorSpace。Core Graphics 将组件复制到内部表示中,并创建与色彩空间的关联。之后,颜色就可以在任何图形操作中使用了——填充、描边、渐变、阴影。

通过 ColorSync 进行色彩管理

macOS 上,色彩管理通过集成到 Core Graphics 中的 ColorSync 框架进行。ColorSync 跟踪显示器的校准,并自动将组件从源色彩空间转换到目标设备的空间。在 iOS 上,色彩管理通过 Quartz Core 实现,从 iPhone 7 开始支持宽色域(Display P3)。

CGColorSpace 中的主要颜色模型

CGColorSpace 支持四种基本颜色模型:RGB(DeviceRGB、sRGB、Display P3)、Gray(DeviceGray)、CMYK(DeviceCMYK)和 Lab。每个模型决定了颜色组件的数量和含义。RGB 使用三个通道——红色、绿色、蓝色;Gray——一个亮度通道;CMYK——四个打印通道;Lab——三个通道:亮度和两个色差分量。

颜色模型组件应用CGColorSpace 类型
RGBRed, Green, Blue屏幕,iOS/macOS 图形kCGColorSpaceSRGB
GrayWhite(单通道)黑白图形,阴影kCGColorSpaceGenericGray
CMYKCyan, Magenta, Yellow, Black印刷产品,PDFkCGColorSpaceGenericCMYK
Display P3R, G, B(宽色域)现代 iOS 设备kCGColorSpaceDisplayP3

DeviceRGB 和 sRGB

DeviceRGB — 是 Core Graphics 最常见的默认色彩空间。它使用标准 LCD 显示器的色域,没有 ICC 配置文件。在创建 UIView 或 NSView 的图形上下文时,Core Graphics 会自动分配 DeviceRGB 作为默认色彩空间。sRGB——带有 ICC 配置文件的版本,具有固定的色域和伽马值,推荐用于 Web 内容。

Display P3——宽色域

Display P3 — 基于 DCI-P3 标准的色彩空间,用于具有宽色域显示器的现代 iOS 设备。它覆盖的可��颜色比 sRGB 多大约 25%,特别是在光谱的绿色和红色区域。要在 iOS 上使用 Display P3,需要使用常量 kCGColorSpaceDisplayP3,从 iOS 9.3 开始可用。

创建和管理 CGColor

CGColor 通过 CGColorCreate 函数创建,该函数接受 CGColorSpace 和 CGFloat 类型的组件数组。组件的数量取决于颜色模型:Gray 为 1,RGB 为 3,CMYK 为 4。创建后,CGColor 是一个不可变对象——不能更改其组件,只能创建新的颜色。

Core Graphics 还提供了 CGColorCreateGenericRGBCGColorCreateGenericGrayCGColorCreateGenericCMYK 函数,用于在标准(通用)色彩空间中创建颜色。这些函数简化了代码,无需显式创建 CGColorSpace。此外,在 Quartz 2D 中定义了基本颜色的常量:kCGColorWhitekCGColorBlackkCGColorClear

在创建颜色时,组件的指定顺序很重要——必须严格符合色彩空间模型定义的通道顺序。RGB:红色 (0.0–1.0)、绿色、蓝色、透明度 (0.0–1.0)。Gray:亮度、透明度。CMYK:青色、品红色、黄色、黑色、透明度。组件顺序错误会导致颜色显示不正确,而不会出现编译错误。

透明度通道和透明度

透明度通道——控制颜色透明度的第四个组件(或 Gray 的第二个组件)。值 1.0 表示完全不透明,0.0 表示完全透明。CGColor 中的透明度通道是可选的:CGColorGetAlpha 函数返回当前的透明度值,通过基本函数创建时默认为 1.0。在颜色混合时,Core Graphics 根据 Porter-Duff Source Over 规则使用透明度合成。

使用 CGColorSpace

CGColorSpace 通过 Core Graphics 的工厂函数创建:CGColorSpaceCreateDeviceRGBCGColorSpaceCreateDeviceGrayCGColorSpaceCreateDeviceCMYK 或用于命名空间的 CGColorSpaceCreateWithName(sRGB、Display P3、Generic Gray)。CGColorSpace 对象是不可变且线程安全的——同一个对象可以在多个图形上下文中使用。

获取基本的 CGColorSpace

Core Graphics 通过命名的常量提供了几个预定义的色彩空间:kCGColorSpaceSRGBkCGColorSpaceDisplayP3kCGColorSpaceGenericGrayGamma2_2。这些常量被传递给 CGColorSpaceCreateWithName。对于具有宽色域的 iOS 设备,建议使用 Display P3,因为 sRGB 可能无法充分利用显示器的能力。

ICC 配置文件和自定义 CGColorSpace

ICC 配置文件——是描述设备颜色特性的标准化文件。Core Graphics 允许通过 CGColorSpaceCreateWithICCProfile 基于任意 ICC 配置文件创建 CGColorSpace。这在专业照片打印和印前应用中使用,需要与特定的打印机或显示器精确匹配。

色彩空间之间的转换

Core Graphics 在通过 CGContextSetFillColorWithColorCGContextSetStrokeColorWithColor 函数绘制时自动执行色彩空间之间的转换。如果图形上下文的色彩空间与传入的 CGColor 的色彩空间不同,Quartz 2D 会使用两个空间的 ICC 配置文件执行转换。

对于显式的颜色转换,使用 CGColorCreateCopyByMatchingToColorSpace——该函数创建一个新的 CGColor,其组件从源空间重新计算到目标空间。根据 Apple Technical Note TN2313 (2024),从 Display P3 转换到 sRGB 时,色域外的颜色会被裁剪,导致饱和度损失。这在鲜艳的绿色和红色色调中尤为明显。

ColorSync 在 macOS 上提供图形堆栈级别的系统色彩管理。如果应用程序没有显式指定色彩空间,Core Graphics 会使用从 ColorSync 获取的显示空间。这保证了即使显示器使用不同的颜色配置文件,颜色也会看起来相同。

Swift 代码示例

让我们来看一下在 iOS 应用程序中创建和使用 CGColor 和 CGColorSpace 的 实际示例。代码使用 Swift 编写,使用 Core Graphics 函数。

在不同色彩空间中创建 CGColor

此示例展示了在三种不同色彩空间中创建红色。尽管 RGB 组件相同,但颜色会根据 CGColorSpace 的色域而不同。

swift
import CoreGraphics

// 在 DeviceRGB 中创建颜色
let rgbSpace = CGColorSpaceCreateDeviceRGB()
let redColor = CGColorCreate(rgbSpace, [1.0, 0.0, 0.0, 1.0])

// 在 Display P3 中创建颜色
let p3Space = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3)
let p3RedColor = CGColorCreate(p3Space, [1.0, 0.0, 0.0, 1.0])

// 创建灰色
let graySpace = CGColorSpaceCreateDeviceGray()
let grayColor = CGColorCreate(graySpace, [0.5, 1.0])

颜色在色彩空间之间的转换

示例中将 亮绿色 从 Display P3 转换到 sRGB。在这种转换中,sRGB 色域外的颜色将被调整,可能会改变色调。

swift
let p3Space = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3)
let sRGBSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB)

// Display P3 中的亮绿色(sRGB 色域外)
let p3Green = CGColorCreate(p3Space, [0.0, 1.0, 0.0, 1.0])

// 转换为 sRGB
let srgbGreen = CGColorCreateCopyByMatchingToColorSpace(
    sRGBSpace, p3Green, kCGRenderingIntentDefault
)

在图形上下文中使用 CGColor

此示例演示了在自定义 UIView 中使用 CGColor 绘制填充圆draw 方法获取当前图形上下文 UIGraphicsGetCurrentContext,在其中设置填充颜色。

swift
class ColorView: UIView {
    override func draw(rect: CGRect) {
        guard let ctx = UIGraphicsGetCurrentContext()
        else { return }

        let rgbSpace = CGColorSpaceCreateDeviceRGB()
        let blueColor = CGColorCreate(
            rgbSpace,
            [0.2, 0.4, 1.0, 1.0]
        )

        ctx.setFillColor(blueColor)
        ctx.fillEllipse(in: CGRect(x: 50, y: 50,
                                  width: 200, height: 200))
    }
}

常见问题

CGColor 和 UIColor 有什么区别?

CGColor — 是来自 Core Graphics 的低级颜色表示,用于 C 风格的 API。UIColor — 是 UIKit 的高级包装器,内部存储 CGColor 并添加了对暗模式差异(traitCollection)的支持。UIColor 可以通过 .cgColor 属性转换为 CGColor。

为什么需要为 CGColor 指定色彩空间?

色彩空间 决定了数值组件如何被解释为可见颜色。相同的数字集合(1.0, 0.0, 0.0)在 RGB 中是红色,但在 CMYK 中是青色。没有 CGColorSpace,Core Graphics 无法在具有独特显示器特性的特定设备上正确显示颜色。

iOS 中默认使用什么色彩空间?

iOS 上,UIView 的图形上下文默认使用 DeviceRGB 色彩空间创建。在具有宽色域显示器的设备上(iPad Pro 9.7 英寸及更新型号,iPhone 7 及更新型号),还可以使用 Display P3,它比标准 sRGB 多支持 25% 的颜色。

创建后可以更改 CGColor 的组件吗?

不能,CGColor 是一个不可变对象。要获得具有不同组件的颜色,需要通过 CGColorCreate 创建新的 CGColor。这符合 Core Graphics 的设计,其中大多数对象都是不可变的,以确保线程安全性和绘制的可预测性。

如何将 CGColor 从 RGB 转换为 CMYK?

要进行转换,请使用带有目标 CMYK 空间的 CGColorCreateCopyByMatchingToColorSpace。Core Graphics 将通过 ICC 配置文件考虑渲染意图执行转换。打印时选择 kCGRenderingIntentRelativeColorimetric,照片级图像选择 kCGRenderingIntentPerceptual

总结

  • CGColor — 带有组件和色彩空间引用的不可变颜色对象
  • CGColorSpace — 定义颜色模型(RGB、Gray、CMYK)和可表示颜色范围
  • DeviceRGB — iOS 和 macOS 图形上下文的默认色彩空间
  • Display P3 — 适用于现代 Apple 设备的宽色域空间,覆盖范围比 sRGB 大 25%
  • ICC 配置文件 通过 ColorSync 确保不同设备之间的准确颜色转换
  • 透明度通道 — 参与 Porter-Duff 合成的可选透明度组件
  • 转换 在绘制时自动进行,或通过 CGColorCreateCopyByMatchingToColorSpace 显式进行

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读