Открыть сервис

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 →