Làm việc với màu sắc trong Core Graphics được xây dựng xung quanh hai thực thể có liên quan với nhau — CGColor và CGColorSpace. CGColor đại diện cho một màu cụ thể với các thành phần, trong khi CGColorSpace xác định mô hình giải thích các thành phần đó. Theo Apple Documentation (2026), Core Graphics hỗ trợ hơn 20 không gian màu tiêu chuẩn, bao gồm sRGB, Generic Gray và Generic CMYK. Hiểu sự khác biệt giữa CGColor và CGColorSpace là cần thiết để hiển thị đồ họa chính xác trên iOS và macOS.
Những điểm chính
CGColor là một đối tượng cơ bản của Core Graphics đại diện cho màu sắc. Cấu trúc CGColor lưu trữ các giá trị số của thành phần màu và tham chiếu đến CGColorSpace — không gian màu trong đó các thành phần này được giải thích. Nếu không gắn với không gian màu, các giá trị số của thành phần không có ý nghĩa: giá trị (1.0, 0.0, 0.0) trong RGB là màu đỏ, nhưng trong CMYK là màu lục lam.
CGColorSpace là một đối tượng xác định mô hình màu và phạm vi giá trị có thể biểu diễn (gamut). Không gian màu đặt ra các quy tắc mà theo đó các thành phần số biến thành màu hiển thị trên một thiết bị đầu ra cụ thể. Core Graphics hỗ trợ cả không gian ICC tiêu chuẩn và không gian tùy chỉnh được tạo qua CGColorSpace với bảng chuyển đổi tùy chỉnh.
Kiến trúc tách màu sắc khỏi không gian màu là một tính năng chính của Core Graphics giúp phân biệt nó với các API nơi màu sắc được lưu trữ dưới dạng một tập hợp số đơn giản. Cách tiếp cận này cho phép Core Graphics thực hiện quản lý màu độc lập với thiết bị: cùng một đối tượng CGColor có thể được hiển thị chính xác trên các màn hình khác nhau nhờ chuyển đổi thành phần tự động qua hồ sơ CGColorSpace.
Core Graphics triển khai màu sắc thông qua mô hình dựa trên hồ sơ ICC (International Color Consortium). Mỗi CGColorSpace chứa tham chiếu đến hồ sơ ICC — một mô tả tiêu chuẩn về cách các thành phần màu được chuyển đổi thành CIE XYZ — một không gian màu độc lập với thiết bị. Điều này cho phép Core Graphics thực hiện bù màu tự động giữa các màn hình khác nhau.
Khi tạo CGColor qua hàm CGColorCreate, các thành phần được lấy từ mảng được truyền vào và gắn với CGColorSpace được chỉ định. Core Graphics sao chép các thành phần vào biểu diễn nội bộ và tạo liên kết với không gian màu. Sau đó, màu sắc đã sẵn sàng để sử dụng trong bất kỳ thao tác đồ họa nào — tô màu, viền, gradient, bóng đổ.
Trên macOS, quản lý màu được xử lý thông qua framework ColorSync, tích hợp trong Core Graphics. ColorSync theo dõi hiệu chỉnh màn hình và tự động chuyển đổi các thành phần từ không gian màu nguồn sang không gian thiết bị đích. Trên iOS, quản lý màu được triển khai qua Quartz Core với hỗ trợ dải màu rộng (Display P3), bắt đầu từ iPhone 7.
CGColorSpace hỗ trợ bốn mô hình màu cơ bản: RGB (DeviceRGB, sRGB, Display P3), Gray (DeviceGray), CMYK (DeviceCMYK) và Lab. Mỗi mô hình xác định số lượng và ý nghĩa của các thành phần màu. RGB sử dụng ba kênh — đỏ, lục, lam; Gray sử dụng một kênh độ chói; CMYK sử dụng bốn kênh cho in ấn; Lab sử dụng ba kênh: độ chói và hai thành phần chênh lệch màu.
| Mô hình màu | Các thành phần | Sử dụng | Loại CGColorSpace |
|---|---|---|---|
| RGB | Đỏ, Lục, Lam | Màn hình, đồ họa iOS/macOS | kCGColorSpaceSRGB |
| Gray | Trắng (một kênh) | Đồ họa đen trắng, bóng đổ | kCGColorSpaceGenericGray |
| CMYK | Lục lam, Đỏ tươi, Vàng, Đen | Sản phẩm in ấn, PDF | kCGColorSpaceGenericCMYK |
| Display P3 | R, G, B (dải màu rộng) | Thiết bị iOS hiện đại | kCGColorSpaceDisplayP3 |
DeviceRGB là không gian màu mặc định phổ biến nhất của Core Graphics. Nó sử dụng dải màu của màn hình LCD tiêu chuẩn mà không có hồ sơ ICC. Khi tạo ngữ cảnh đồ họa UIView hoặc NSView, Core Graphics tự động gán DeviceRGB làm không gian màu mặc định. sRGB là phiên bản có hồ sơ ICC với dải màu và gamma cố định, được khuyến nghị cho nội dung web.
Display P3 là không gian màu dựa trên tiêu chuẩn DCI-P3, được sử dụng trong các thiết bị iOS hiện đại có màn hình dải màu rộng. Nó bao phủ khoảng 25% màu hiển thị nhiều hơn sRGB, đặc biệt là trong các vùng xanh lục và đỏ của quang phổ. Để làm việc với Display P3 trên iOS, sử dụng hằng số kCGColorSpaceDisplayP3, có sẵn từ iOS 9.3.
CGColor được tạo qua hàm CGColorCreate, nhận CGColorSpace và một mảng các thành phần CGFloat. Số lượng thành phần phụ thuộc vào mô hình màu: 1 cho Gray, 3 cho RGB, 4 cho CMYK. Sau khi được tạo, CGColor là một đối tượng bất biến (immutable) — bạn không thể thay đổi các thành phần của nó, chỉ có thể tạo màu mới.
Core Graphics cũng cung cấp các hàm CGColorCreateGenericRGB, CGColorCreateGenericGray và CGColorCreateGenericCMYK để tạo màu trong các không gian màu tiêu chuẩn (chung). Các hàm này đơn giản hóa mã bằng cách loại bỏ nhu cầu tạo CGColorSpace một cách tường minh. Ngoài ra, Quartz 2D định nghĩa các hằng số cho màu cơ bản: kCGColorWhite, kCGColorBlack, kCGColorClear.
Khi tạo màu, thứ tự chỉ định các thành phần rất quan trọng — phải khớp chính xác với thứ tự kênh được xác định bởi mô hình không gian màu. RGB: đỏ (0.0–1.0), lục, lam, alpha (0.0–1.0). Gray: độ chói, alpha. CMYK: lục lam, đỏ tươi, vàng, đen, alpha. Vi phạm thứ tự thành phần dẫn đến hiển thị màu không chính xác mà không có lỗi biên dịch.
Kênh alpha là thành phần thứ tư (hoặc thứ hai cho Gray) kiểm soát độ trong suốt của màu. Giá trị 1.0 tương ứng với độ mờ đục hoàn toàn, 0.0 với độ trong suốt hoàn toàn. Kênh alpha trong CGColor là tùy chọn: hàm CGColorGetAlpha trả về giá trị alpha hiện tại, mặc định là 1.0 khi được tạo qua các hàm cơ bản. Khi pha trộn màu sắc, Core Graphics sử dụng tổng hợp alpha theo quy tắc Porter-Duff Source Over.
CGColorSpace được tạo qua các hàm factory của Core Graphics: CGColorSpaceCreateDeviceRGB, CGColorSpaceCreateDeviceGray, CGColorSpaceCreateDeviceCMYK hoặc CGColorSpaceCreateWithName cho các không gian có tên (sRGB, Display P3, Generic Gray). Đối tượng CGColorSpace là bất biến và an toàn luồng — cùng một đối tượng có thể được sử dụng trong nhiều ngữ cảnh đồ họa.
Core Graphics cung cấp một số không gian màu được xác định trước qua các hằng số có tên: kCGColorSpaceSRGB, kCGColorSpaceDisplayP3, kCGColorSpaceGenericGrayGamma2_2. Các hằng số này được truyền vào CGColorSpaceCreateWithName. Đối với thiết bị iOS có dải màu rộng, Display P3 được khuyến nghị vì sRGB có thể không sử dụng hết khả năng của màn hình.
Hồ sơ ICC là các tệp tiêu chuẩn hóa mô tả đặc điểm màu sắc của thiết bị. Core Graphics cho phép tạo CGColorSpace dựa trên hồ sơ ICC tùy ý qua CGColorSpaceCreateWithICCProfile. Điều này được sử dụng trong các ứng dụng chuyên nghiệp cho in ảnh và tiền in ấn nơi cần khớp chính xác với một máy in hoặc màn hình cụ thể.
Core Graphics thực hiện chuyển đổi giữa các không gian màu tự động trong quá trình kết xuất qua các hàm CGContextSetFillColorWithColor hoặc CGContextSetStrokeColorWithColor. Nếu không gian màu của ngữ cảnh đồ họa khác với không gian màu của CGColor được truyền vào, Quartz 2D thực hiện chuyển đổi bằng cách sử dụng hồ sơ ICC của cả hai không gian.
Để chuyển đổi màu tường minh, sử dụng CGColorCreateCopyByMatchingToColorSpace — một hàm tạo CGColor mới có các thành phần được tính toán lại từ không gian nguồn sang không gian đích. Theo Apple Technical Note TN2313 (2024), khi chuyển đổi từ Display P3 sang sRGB, các màu ngoài dải sRGB bị cắt, dẫn đến mất độ bão hòa. Điều này đặc biệt đáng chú ý ở các tông màu xanh lục và đỏ tươi.
ColorSync trên macOS cung cấp quản lý màu cấp hệ thống ở tầng đồ họa. Nếu ứng dụng không chỉ định không gian màu tường minh, Core Graphics sử dụng không gian màn hình lấy từ ColorSync. Điều này đảm bảo màu sắc trông giống nhau trên các màn hình khác nhau, ngay cả khi chúng sử dụng hồ sơ màu khác nhau.
Hãy xem các ví dụ thực tế về tạo và sử dụng CGColor và CGColorSpace trong ứng dụng iOS. Mã được viết bằng Swift sử dụng các hàm Core Graphics.
Ví dụ này cho thấy tạo màu đỏ trong ba không gian màu khác nhau. Mặc dù có cùng thành phần RGB, màu sắc sẽ trông khác nhau tùy thuộc vào dải màu của CGColorSpace.
import CoreGraphics
// Tạo màu trong DeviceRGB
let rgbSpace = CGColorSpaceCreateDeviceRGB()
let redColor = CGColorCreate(rgbSpace, [1.0, 0.0, 0.0, 1.0])
// Tạo màu trong Display P3
let p3Space = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3)
let p3RedColor = CGColorCreate(p3Space, [1.0, 0.0, 0.0, 1.0])
// Tạo màu xám
let graySpace = CGColorSpaceCreateDeviceGray()
let grayColor = CGColorCreate(graySpace, [0.5, 1.0])
Ví dụ này chuyển đổi màu xanh lục tươi từ Display P3 sang sRGB. Trong quá trình chuyển đổi như vậy, các màu ngoài dải sRGB sẽ được thích ứng, có thể thay đổi tông màu.
let p3Space = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3)
let sRGBSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB)
// Xanh lục tươi trong Display P3 (ngoài dải sRGB)
let p3Green = CGColorCreate(p3Space, [0.0, 1.0, 0.0, 1.0])
// Chuyển đổi sang sRGB
let srgbGreen = CGColorCreateCopyByMatchingToColorSpace(
sRGBSpace, p3Green, kCGRenderingIntentDefault
)
Ví dụ này minh họa vẽ một hình tròn được tô màu sử dụng CGColor trong UIView tùy chỉnh. Phương thức draw lấy ngữ cảnh đồ họa hiện tại UIGraphicsGetCurrentContext, trong đó màu tô được thiết lập.
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))
}
}
Các câu hỏi thường gặp
CGColor là biểu diễn màu cấp thấp từ Core Graphics được sử dụng trong API kiểu C. UIColor là một wrapper cấp cao của UIKit lưu trữ nội bộ CGColor và thêm hỗ trợ cho sự khác biệt chế độ tối (traitCollection). UIColor có thể được chuyển đổi thành CGColor qua thuộc tính .cgColor.
Không gian màu xác định cách các thành phần số được giải thích thành màu hiển thị. Cùng một tập hợp số (1.0, 0.0, 0.0) có nghĩa là màu đỏ trong RGB nhưng màu lục lam trong CMYK. Không có CGColorSpace, Core Graphics không thể hiển thị màu chính xác trên một thiết bị cụ thể với các đặc điểm màn hình độc đáo của nó.
Trên iOS, ngữ cảnh đồ họa UIView được tạo mặc định với không gian màu DeviceRGB. Trên các thiết bị có màn hình dải màu rộng (iPad Pro 9,7 inch trở lên, iPhone 7 trở lên), Display P3 cũng có sẵn, hỗ trợ nhiều hơn 25% màu sắc so với sRGB tiêu chuẩn.
Không, CGColor là một đối tượng bất biến (immutable). Để có màu với các thành phần khác, bạn phải tạo CGColor mới qua CGColorCreate. Điều này tuân theo thiết kế của Core Graphics nơi hầu hết các đối tượng là bất biến để đảm bảo an toàn luồng và khả năng dự đoán kết xuất.
Để chuyển đổi, sử dụng CGColorCreateCopyByMatchingToColorSpace với không gian CMYK đích. Core Graphics sẽ thực hiện chuyển đổi qua hồ sơ ICC có tính đến mục đích kết xuất. Chọn kCGRenderingIntentRelativeColorimetric cho in ấn hoặc kCGRenderingIntentPerceptual cho hình ảnh chân thực.
Tổng kết
CGColorCreateCopyByMatchingToColorSpaceChúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm