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-базирано управление на цветовете за точно цветопредаване между устройства
  • Преобразуването между цветови пространства се извършва чрез ColorSync на macOS и чрез Quartz Core на iOS

Какво са CGColor и CGColorSpace?

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

Core Graphics имплементира цвета чрез модел, базиран на ICC профили (International Color Consortium). Всяко CGColorSpace съдържа препратка към ICC профил — стандартизирано описание на това как цветовите компоненти се преобразуват в CIE XYZ — независимо от хардуера цветово пространство. Това позволява на Core Graphics да извършва автоматична колориметрична компенсация между различни екрани.

Жизнен цикъл на CGColor обекта

При създаване на CGColor чрез функцията CGColorCreate компонентите се извличат от подадения масив и се свързват с посоченото CGColorSpace. Core Graphics копира компонентите във вътрешно представяне и създава асоциация с цветовото пространство. След това цветът е готов за използване във всяка графична операция — запълване, контур, градиент, сянка.

Управление на цветовете чрез ColorSync

На macOS управлението на цветовете се осъществява чрез рамката ColorSync, интегрирана в Core Graphics. ColorSync проследява калибрирането на екрана и автоматично преобразува компонентите от цветовото пространство на източника в пространството на целевото устройство. На iOS управлението на цветовете е имплементирано чрез Quartz Core с поддръжка на широк цветови обхват (Display P3), започвайки от iPhone 7.

Основни цветови модели в CGColorSpace

CGColorSpace поддържа четири основни цветови модела: RGB (DeviceRGB, sRGB, Display P3), Gray (DeviceGray), CMYK (DeviceCMYK) и Lab. Всеки модел определя броя и значението на цветовите компоненти. RGB използва три канала — червен, зелен, син; Gray — един канал за яркост; CMYK — четири канала за печат; Lab — три канала: яркост и две компоненти за цветова разлика.

Цветови моделКомпонентиПриложениеТип CGColorSpace
RGBRed, Green, BlueЕкрани, графика за iOS/macOSkCGColorSpaceSRGB
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-профилирана версия с фиксиран обхват и гама, препоръчана за уеб съдържание.

Display P3 — широк цветови обхват

Display P3 — цветово пространство, базирано на стандарта DCI-P3, използвано в съвременни iOS устройства с дисплеи с широк цветови обхват. То покрива приблизително 25% повече видими цветове от sRGB, особено в зелената и червената област на спектъра. За работа с Display P3 на iOS се използва константата kCGColorSpaceDisplayP3, достъпна от iOS 9.3.

Създаване и управление на CGColor

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

CGColorSpace се създава чрез фабрични функции на Core Graphics: CGColorSpaceCreateDeviceRGB, CGColorSpaceCreateDeviceGray, CGColorSpaceCreateDeviceCMYK или CGColorSpaceCreateWithName за именувани пространства (sRGB, Display P3, Generic Gray). Обектът CGColorSpace е неизменяем и thread-safe — един и същ обект може да се използва в множество графични контексти.

Получаване на основни CGColorSpace

Core Graphics предоставя няколко предефинирани цветови пространства чрез именувани константи: kCGColorSpaceSRGB, kCGColorSpaceDisplayP3, kCGColorSpaceGenericGrayGamma2_2. Тези константи се подават на CGColorSpaceCreateWithName. За iOS устройства с широк цветови обхват се препоръчва използването на Display P3, тъй като sRGB може да не използва напълно възможностите на дисплея.

ICC профили и персонализирано CGColorSpace

ICC профили — са стандартизирани файлове, описващи цветовите характеристики на устройството. Core Graphics позволява създаване на CGColorSpace на базата на произволен ICC профил чрез CGColorSpaceCreateWithICCProfile. Това се използва в професионални приложения за фотопечат и prepress, където се изисква точно съответствие с конкретен принтер или монитор.

Преобразуване между цветови пространства

Core Graphics извършва преобразуване между цветови пространства автоматично при рисуване чрез функцията CGContextSetFillColorWithColor или CGContextSetStrokeColorWithColor. Ако цветовото пространство на графичния контекст се различава от цветовото пространство на подадения CGColor, Quartz 2D извършва конвертиране, използвайки ICC профили на двете пространства.

За изрично преобразуване на цвят се използва CGColorCreateCopyByMatchingToColorSpace — функцията създава нов CGColor, чиито компоненти са преизчислени от изходното пространство в целевото. Според Apple Technical Note TN2313 (2024), при преобразуване от Display P3 в sRGB цветовете извън обхвата на sRGB се отрязват, което води до загуба на наситеност. Това е особено забележимо при яркозелени и червени нюанси.

ColorSync на macOS осигурява системно управление на цветовете на ниво графичен стек. Ако приложението не задава изрично цветово пространство, Core Graphics използва пространството на екрана, получено от ColorSync. Това гарантира, че цветовете ще изглеждат еднакво на различни монитори, дори ако те използват различни цветови профили.

Примери за код в Swift

Нека разгледаме практически примери за създаване и използване на CGColor и CGColorSpace в iOS приложение. Кодът е написан на 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 в графичен контекст

Този пример демонстрира рисуване на запълнен кръг с използване на CGColor в персонализиран UIView. Методът 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, което поддържа 25% повече цветове от стандартното sRGB.

Могат ли компонентите на CGColor да бъдат променени след създаване?

Не, CGColor е неизменяем (immutable) обект. За получаване на цвят с различни компоненти е необходимо да се създаде нов CGColor чрез CGColorCreate. Това е в съответствие с дизайна на Core Graphics, където повечето обекти са неизменяеми за осигуряване на нишкова безопасност и предвидимост на рисуването.

Как да преобразуваме CGColor от RGB в CMYK?

За преобразуване използвайте CGColorCreateCopyByMatchingToColorSpace с целевото CMYK пространство. Core Graphics ще извърши конвертиране чрез ICC профили, като вземе предвид рендеринг intent. Изберете kCGRenderingIntentRelativeColorimetric за печат или kCGRenderingIntentPerceptual за фотореалистични изображения.

Резюме

  • CGColor — неизменяем цветови обект с компоненти и препратка към цветово пространство
  • CGColorSpace — определя цветовия модел (RGB, Gray, CMYK) и обхвата на представимите цветове
  • DeviceRGB — цветово пространство по подразбиране за графичен контекст на iOS и macOS
  • Display P3 — широкоспектърно пространство за съвременни Apple устройства с покритие 25% по-голямо от sRGB
  • ICC профили осигуряват точно преобразуване на цветовете между различни устройства чрез ColorSync
  • Алфа канал — опционален компонент за прозрачност, участващ в Porter-Duff композита
  • Преобразуване между пространства се извършва автоматично при рисуване или изрично чрез CGColorCreateCopyByMatchingToColorSpace

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също