Робота з кольором в Core Graphics будується навколо двох взаємопов'язаних сутностей — CGColor і CGColorSpace. CGColor представляє конкретний колір з компонентами, а CGColorSpace визначає модель інтерпретації цих компонентів. За даними Apple Documentation (2026), Core Graphics підтримує понад 20 стандартних колірних просторів, включаючи sRGB, Generic Gray і Generic CMYK. Розуміння різниці між CGColor і CGColorSpace необхідне для коректного відтворення графіки на iOS і macOS.
Головне
CGColor — це фундаментальний об'єкт Core Graphics, що представляє колір. У структурі CGColor зберігаються числові значення колірних компонентів і посилання на CGColorSpace — колірний простір, у якому ці компоненти інтерпретуються. Без прив'язки до колірного простору числові значення компонентів не мають сенсу: значення (1.0, 0.0, 0.0) в RGB — це червоний, а в CMYK — блакитний (Cyan).
CGColorSpace — це об'єкт, що визначає модель кольору та діапазон представлених значень (gamut). Колірний простір задає правила, за якими числові компоненти перетворюються на видимий колір на конкретному пристрої виведення. Core Graphics підтримує як стандартні ICC-профільовані простори, так і користувацькі простори, створювані через CGColorSpace з кастомними таблицями перетворення.
Архітектура розділення кольору та колірного простору — ключова особливість Core Graphics, що відрізняє її від API, де колір зберігається як простий набір чисел. Такий підхід дозволяє Core Graphics виконувати апаратно-незалежне управління кольором: один і той самий об'єкт CGColor може бути коректно відображений на різних дисплеях завдяки автоматичному перетворенню компонентів через профіль CGColorSpace.
Core Graphics реалізує колір через модель, засновану на ICC-профілях (International Color Consortium). Кожен CGColorSpace містить посилання на ICC-профіль — стандартизований опис того, як колірні компоненти перетворюються в CIE XYZ — апаратно-незалежний колірний простір. Це дозволяє Core Graphics виконувати автоматичну колориметричну компенсацію між різними екранами.
При створенні CGColor через функцію CGColorCreate відбувається захоплення компонентів з переданого масиву та прив'язка до вказаного CGColorSpace. Core Graphics копіює компоненти у внутрішнє представлення та створює асоціацію з колірним простором. Після цього колір готовий до використання в будь-якій графічній операції — заливка, обведення, градієнт, тінь.
На macOS управління кольором здійснюється через фреймворк ColorSync, інтегрований в Core Graphics. ColorSync відстежує калібрування дисплея та автоматично перетворює компоненти з колірного простору джерела в простір цільового пристрою. На iOS управління кольором реалізовано через Quartz Core з підтримкою широкого колірного охоплення (Display P3), починаючи з iPhone 7.
CGColorSpace підтримує чотири базові колірні моделі: RGB (DeviceRGB, sRGB, Display P3), Gray (DeviceGray), CMYK (DeviceCMYK) і Lab. Кожна модель визначає кількість і значення колірних компонентів. RGB використовує три канали — червоний, зелений, синій; Gray — один канал яскравості; CMYK — чотири канали для друку; Lab — три канали: яскравість і дві кольорорізницеві компоненти.
| Колірна модель | Компоненти | Застосування | Тип CGColorSpace |
|---|---|---|---|
| RGB | Червоний, Зелений, Синій | Екрани, графіка для iOS/macOS | kCGColorSpaceSRGB |
| Gray | Білий (один канал) | Чорно-біла графіка, тіні | kCGColorSpaceGenericGray |
| CMYK | Блакитний, Пурпурний, Жовтий, Чорний | Друкована продукція, PDF | kCGColorSpaceGenericCMYK |
| Display P3 | R, G, B (широке охоплення) | Сучасні iOS-пристрої | kCGColorSpaceDisplayP3 |
DeviceRGB — це найпоширеніший колірний простір Core Graphics за замовчуванням. Він використовує колірне охоплення стандартного LCD-дисплея без ICC-профілювання. При створенні графічного контексту UIView або NSView Core Graphics автоматично призначає DeviceRGB як колірний простір за замовчуванням. sRGB — ICC-профільована версія з фіксованим охопленням і гаммою, рекомендована для веб-контенту.
Display P3 — колірний простір, заснований на стандарті DCI-P3, що використовується в сучасних iOS-пристроях з ширококолірними дисплеями. Він охоплює приблизно на 25% більше видимих кольорів, ніж sRGB, особливо в зеленій і червоній областях спектра. Для роботи з Display P3 на iOS використовується константа kCGColorSpaceDisplayP3, доступна з iOS 9.3.
CGColor створюється через функцію CGColorCreate, яка приймає CGColorSpace і масив компонентів типу CGFloat. Кількість компонентів залежить від колірної моделі: для Gray — 1, для RGB — 3, для CMYK — 4. Після створення CGColor є незмінним (immutable) об'єктом — змінити його компоненти не можна, можна лише створити новий колір.
Core Graphics надає також функції CGColorCreateGenericRGB, CGColorCreateGenericGray і CGColorCreateGenericCMYK для створення кольорів у стандартних (generic) колірних просторах. Ці функції спрощують код, позбавляючи від необхідності явно створювати CGColorSpace. Крім того, в Quartz 2D визначено константи основних кольорів: kCGColorWhite, kCGColorBlack, kCGColorClear.
При створенні кольору важливий порядок завдання компонентів — він повинен строго відповідати порядку каналів, визначеному моделлю колірного простору. 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 створюється через фабричні функції Core Graphics: CGColorSpaceCreateDeviceRGB, CGColorSpaceCreateDeviceGray, CGColorSpaceCreateDeviceCMYK або CGColorSpaceCreateWithName для іменованих просторів (sRGB, Display P3, Generic Gray). Об'єкт CGColorSpace є незмінним і потокобезпечним — один і той самий об'єкт може використовуватися в кількох графічних контекстах.
Core Graphics надає кілька попередньо визначених колірних просторів через іменовані константи: kCGColorSpaceSRGB, kCGColorSpaceDisplayP3, kCGColorSpaceGenericGrayGamma2_2. Ці константи передаються в CGColorSpaceCreateWithName. Для пристроїв iOS з широким колірним охопленням рекомендується використовувати Display P3, оскільки sRGB може не повністю використовувати можливості дисплея.
ICC-профілі — це стандартизовані файли, що описують колірні характеристики пристрою. Core Graphics дозволяє створювати CGColorSpace на основі довільного ICC-профілю через CGColorSpaceCreateWithICCProfile. Це використовується в професійних додатках для фотодруку та препреса, де потрібна точна відповідність певному принтеру або монітору.
Core Graphics виконує перетворення між колірними просторами автоматично при відтворенні через функцію CGContextSetFillColorWithColor або CGContextSetStrokeColorWithColor. Якщо колірний простір графічного контексту відрізняється від колірного простору переданого CGColor, Quartz 2D виконує конвертацію з використанням ICC-профілів обох просторів.
Для явного перетворення кольору використовується CGColorCreateCopyByMatchingToColorSpace — функція створює новий CGColor, компоненти якого перераховані з вихідного простору в цільовий. За даними Apple Technical Note TN2313 (2024), при перетворенні з Display P3 в sRGB кольори за межами охоплення sRGB кліпуються, що призводить до втрати насиченості. Це особливо помітно на яскравих зелених і червоних відтінках.
ColorSync на macOS забезпечує системне управління кольором на рівні графічного стека. Якщо додаток не задає явного колірного простору, Core Graphics використовує простір дисплея, отриманий від ColorSync. Це гарантує, що кольори виглядатимуть однаково на різних моніторах, навіть якщо вони використовують різні колірні профілі.
Розглянемо практичні приклади створення та використання CGColor і CGColorSpace в iOS-додатку. Код написаний на Swift з використанням функцій Core Graphics.
У цьому прикладі показано створення червоного кольору в трьох різних колірних просторах. Незважаючи на однакові RGB-компоненти, колір виглядатиме по-різному залежно від колірного охоплення CGColorSpace.
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-охоплення будуть адаптовані, що може змінити відтінок.
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. Метод draw отримує поточний графічний контекст UIGraphicsGetCurrentContext, у якому задається колір заливки.
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 — це низькорівневе представлення кольору з Core Graphics, що використовується в C-стилі API. UIColor — це високорівнева обгортка UIKit, яка всередині зберігає CGColor і додає підтримку відмінностей у темному режимі (traitCollection). UIColor можна перетворити в CGColor через властивість .cgColor.
Колірний простір визначає, як числові компоненти інтерпретуються у видимий колір. Один і той самий набір чисел (1.0, 0.0, 0.0) означає червоний в RGB, але блакитний в CMYK. Без CGColorSpace Core Graphics не може коректно відобразити колір на конкретному пристрої з його унікальними характеристиками дисплея.
На iOS графічний контекст UIView за замовчуванням створюється з колірним простором DeviceRGB. На пристроях з ширококолірним дисплеєм (iPad Pro 9.7 дюйма і новіше, iPhone 7 і новіше) доступне також Display P3, яке підтримує на 25% більше кольорів, ніж стандартне sRGB.
Ні, CGColor є незмінним (immutable) об'єктом. Для отримання кольору з іншими компонентами необхідно створити новий CGColor через CGColorCreate. Це відповідає дизайну Core Graphics, де більшість об'єктів є незмінними для забезпечення потокобезпечності та передбачуваності відтворення.
Для перетворення використовуйте CGColorCreateCopyByMatchingToColorSpace з цільовим CMYK-простором. Core Graphics виконає перетворення через ICC-профілі з урахуванням рендерингового інтенту. Виберіть kCGRenderingIntentRelativeColorimetric для друку або kCGRenderingIntentPerceptual для фотореалістичних зображень.
Підсумки
CGColorCreateCopyByMatchingToColorSpaceМи розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також