CGImageRef
CGImageRef — это тип данных (опaque type) в среде разработки Core Graphics (также известной как Quartz 2D) в операционных системах Apple (macOS, iOS, iPadOS, watchOS, tvOS), представляющий собой неизменяемое растровое изображение. CGImageRef является фундаментальным объектом для работы с пиксельной графикой на низком уровне, предоставляя доступ к данным изображения, его цветовому пространству, битовой глубине и другим метаданным, но не управляя его отображением на экране.
История и контекст
Core Graphics — это фреймворк для 2D-рендеринга, входящий в состав Core Foundation и основанный на движке Quartz. Он был представлен компанией Apple в 2000 году в операционной системе Mac OS X (ныне macOS). CGImageRef был введён как часть этого фреймворка для обеспечения эффективной работы с растровыми изображениями, в отличие от векторных объектов, которые представляются через CGPathRef. В iOS и iPadOS, начиная с первой версии iPhone OS (2007), CGImageRef стал основным способом работы с изображениями на уровне Core Graphics, в то время как более высокоуровневые классы, такие как UIImage (UIKit) или NSImage (AppKit), являются обёртками над CGImageRef.
Структура и свойства
CGImageRef является opaque-типом, что означает, что его внутренняя структура скрыта от разработчика, а доступ к данным осуществляется через функции Core Graphics. Ключевые свойства CGImageRef включают:
- Размер: ширина и высота изображения в пикселях.
- Битовая глубина: количество бит на компонент (например, 8 бит на канал для RGB) и общее количество бит на пиксель.
- Цветовое пространство: объект CGColorSpaceRef, определяющий, как интерпретируются цветовые значения (например, sRGB, линейный RGB, CMYK).
- Альфа-канал: информация о прозрачности, представленная через битовую маску или отдельный канал.
- Порядок байтов: порядок следования байтов в пиксельных данных (например, little-endian или big-endian), что важно для совместимости с разными архитектурами процессоров.
- Растровые данные: указатель на буфер пикселей (CGBitmapInfo), который может быть предоставлен как поставщиком данных (CGDataProviderRef), так и выделен автоматически.
- Маска: опциональная битовая маска для определения прозрачности отдельных пикселей.
Создание и загрузка
CGImageRef создаётся несколькими способами, в зависимости от источника данных:
Загрузка из файла или ресурсов
В iOS и macOS изображение обычно загружается через UIImage или NSImage, а затем извлекается CGImageRef с помощью свойства CGImage: ``objc UIImage uiImage = [UIImage imageNamed:@"example.png"]; CGImageRef cgImage = [uiImage CGImage]; ` В macOS: `objc NSImage nsImage = [NSImage imageNamed:@"example.png"]; CGImageRef cgImage = [nsImage CGImageForProposedRect:NULL context:nil hints:nil]; ``
Создание из пиксельных данных
Для создания CGImageRef из сырых данных используется функция CGImageCreate: ``objc CGImageRef CGImageCreate( size_t width, size_t height, size_t bitsPerComponent, size_t bitsPerPixel, size_t bytesPerRow, CGColorSpaceRef colorSpace, CGBitmapInfo bitmapInfo, CGDataProviderRef provider, const CGFloat *decode, bool shouldInterpolate, CGColorRenderingIntent intent ); `` Параметры включают размеры, цветовое пространство, информацию о битовой карте и поставщик данных (CGDataProviderRef), который может быть создан из буфера памяти, файла или URL.
Копирование и модификация
Поскольку CGImageRef является неизменяемым, для создания изменённой версии изображения (например, с изменённым размером или цветовым пространством) используются функции, такие как CGImageCreateCopy, CGImageCreateWithImageInRect (для обрезки) или CGImageCreateWithMask (для применения маски). Для изменения размера или поворота требуется создать новый контекст (CGBitmapContext) и нарисовать изображение в нём.
Применение
CGImageRef используется в широком спектре задач, связанных с обработкой и отображением растровых изображений:
- Рендеринг в Core Graphics: изображение может быть нарисовано в контексте (CGContextRef) с помощью функции
CGContextDrawImage. Это основа для работы с графикой в пользовательских представлениях, анимациях и эффектах. - Интеграция с Metal и OpenGL: CGImageRef может быть преобразован в текстуру для использования в 3D-графике. Например, в Metal используется функция
MTKTextureLoaderдля загрузки CGImageRef в текстуру. - Обработка изображений: фильтры Core Image (CIFilter) принимают CIImage, который может быть создан из CGImageRef. Это позволяет применять цветокоррекцию, размытие, наложение эффектов и другие преобразования.
- Сохранение в файл: CGImageRef может быть записан в файл с помощью функций Image I/O (например,
CGImageDestinationRef), поддерживающих форматы PNG, JPEG, TIFF и другие. - Анализ пикселей: для низкоуровневого доступа к пиксельным данным (например, для распознавания образов или компьютерного зрения) CGImageRef используется в связке с CGBitmapContext, который позволяет читать и записывать отдельные пиксели.
Управление памятью
CGImageRef является объектом Core Foundation, поэтому для управления памятью используются функции CFRetain и CFRelease (или их макросы, например, CGImageRetain/CGImageRelease). В среде Automatic Reference Counting (ARC) для Objective-C и Swift требуется явное управление, если объект создаётся через функции Core Graphics. В Swift CGImageRef представляется как тип CGImage и автоматически управляется через механизм памяти Swift, но при использовании C-функций необходимо соблюдать правила владения.
Ограничения и особенности
- Неизменяемость: CGImageRef не может быть изменён после создания. Для модификации требуется создание нового изображения через контекст.
- Зависимость от цветового пространства: при работе с изображениями разных цветовых пространств (например, sRGB и Display P3) необходимо учитывать преобразования, иначе цвета могут отображаться некорректно.
- Производительность: создание CGImageRef из больших изображений или с нестандартными параметрами (например, с плавающей точкой) может быть ресурсоёмким. Рекомендуется кэшировать часто используемые объекты.
- Поддержка форматов: CGImageRef поддерживает большинство распространённых растровых форматов, но не все (например, анимированные GIF или многослойные PSD требуют дополнительной обработки).
Примеры использования
Отображение изображения в UIView (iOS)
```objc
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext(); UIImage *image = [UIImage imageNamed:@"photo.jpg"]; CGImageRef cgImage = [image CGImage]; CGContextDrawImage(context, rect, cgImage); } ```
Создание изображения из пиксельных данных
``objc size_t width = 100; size_t height = 100; size_t bytesPerPixel = 4; size_t bytesPerRow = width bytesPerPixel; unsigned char pixelData = malloc(bytesPerRow height); // Заполнение пиксельных данных (например, красный цвет) for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { pixelData[y bytesPerRow + x bytesPerPixel + 0] = 255; // R pixelData[y bytesPerRow + x bytesPerPixel + 1] = 0; // G pixelData[y bytesPerRow + x bytesPerPixel + 2] = 0; // B pixelData[y bytesPerRow + x bytesPerPixel + 3] = 255; // A } } CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixelData, bytesPerRow height, NULL); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGImageRef cgImage = CGImageCreate(width, height, 8, 32, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little, provider, NULL, false, kCGRenderingIntentDefault); // Использование cgImage... CGImageRelease(cgImage); CGColorSpaceRelease(colorSpace); CGDataProviderRelease(provider); free(pixelData); ``
Сравнение с другими типами
- CIImage: представляет изображение в Core Image, может быть ленивым (не содержать пиксельных данных до рендеринга) и поддерживает фильтры. CGImageRef, в отличие от CIImage, всегда содержит готовые пиксельные данные.
- UIImage/NSImage: высокоуровневые обёртки, которые могут содержать CGImageRef внутри. Они предоставляют удобные методы для работы с изображениями, но для низкоуровневых операций требуется прямой доступ к CGImageRef.
- CGContext: не является изображением, а контекстом для рисования. CGImageRef может быть нарисован в контексте, но сам по себе не является контекстом.
Интересные факты
- CGImageRef поддерживает изображения с плавающей точкой (например, 32-битные компоненты), что используется в HDR-графике и профессиональных приложениях.
- В macOS CGImageRef может быть создан из PDF-страницы (через CGPDFPage), хотя PDF является векторным форматом.
- При работе с CGImageRef в многопоточных приложениях необходимо синхронизировать доступ к данным, так как Core Graphics не гарантирует потокобезопасность для всех операций.
Источники
- Apple Inc. Core Graphics Framework Reference. 2023.
- Apple Inc. Quartz 2D Programming Guide. 2022.
- Apple Inc. CGImage Reference. 2023.
- Hillegass, A. Cocoa Programming for Mac OS X. Addison-Wesley, 2012.
- Keur, C., Hillegass, A. iOS Programming: The Big Nerd Ranch Guide. Big Nerd Ranch, 2016.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →