Графические контексты

Графический контекст представляет место назначения получения. Это содержит параметры получения и всю специфичную для устройства информацию, что система получения должна выполнить любые последующие команды рисования. Графический контекст определяет основные атрибуты получения, такие как цвета для использования при рисовании, область отсечения, ширина строки и информация о стилях, информация о шрифтах, составляя опции и несколько других.

Можно получить графический контекст при помощи Кварцевых функций создания контекста или при помощи высокоуровневых функций, предоставленных одной из платформ Mac OS X или платформы UIKit в iOS. Кварц обеспечивает функции для различных разновидностей Кварцевых контекстов графики включая битовый массив и PDF, который можно использовать для создания пользовательского содержания.

Эта глава показывает Вам, как создать графический контекст для множества привлечения мест назначения. Графический контекст представлен в Вашем коде, по условию вводят CGContextRef, который является непрозрачным типом данных. После получения графического контекста можно использовать Кварц 2D функции, чтобы нарисовать к контексту, выполнить операции (такие как переводы) на контексте и изменить параметры состояния графики, такие как ширина строки и цвет заливки.

Рисование к Контексту Графики Представления в iOS

Для рисования на экран в приложении для iOS Вы устанавливаете a UIView возразите и реализуйте drawRect: метод для выполнения получения. Представление drawRect: метод вызывают, когда представление видимо экранный, и его содержанию нужно обновление. Прежде, чем вызвать Ваше пользовательское drawRect: метод, объект представления автоматически конфигурирует свою среду получения так, чтобы Ваш код мог начать рисовать сразу. Как часть этой конфигурации, UIView объект создает графический контекст (a CGContextRef непрозрачный тип) для текущей среды получения. Вы получаете этот графический контекст в Вашем drawRect: метод путем вызывания функции UIKit UIGraphicsGetCurrentContext.

Система координат по умолчанию, используемая всюду по UIKit, отличается от системы координат, используемой Кварцем. В UIKit источник находится в верхнем левом углу с положительным-y значением, указывающим вниз. UIView объект изменяет CTM Кварцевого контекста графики для соответствия соглашений UIKit путем перевода источника в верхний левый угол представления и инвертирования оси y путем умножения его на -1. Для получения дополнительной информации об измененных системах координат и импликациях в Вашем собственном коде для прорисовки, посмотрите Кварц 2D Системы координат.

UIView объекты описаны подробно в поле зрения Руководство по программированию для iOS.

Создание контекста графики окна в Mac OS X

При рисовании в Mac OS X необходимо создать контекст графики окна, это подходяще для платформы, которую Вы используете. Кварц 2D API сам не обеспечивает функций для получения контекста графики окон. Вместо этого Вы используете платформу Какао для получения контекста для окна, создаваемого в Какао.

Вы получаете Кварцевый контекст графики из drawRect: подпрограмма приложения Какао с помощью следующей строки кода:

CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];

Метод currentContext возвраты NSGraphicsContext экземпляр текущего потока. Метод graphicsPort возвращает низкий уровень, специфичный для платформы графический контекст, представленный получателем, который является Кварцевым контекстом графики. (Не запутывайтесь именами методов; они являются историческими.) Для получения дополнительной информации посмотрите Ссылку класса NSGraphicsContext.

После получения графического контекста можно вызвать любой Кварц 2D функции получения в приложении Какао. Можно также смешать Кварц 2D вызовы с вызовами рисования Какао. Вы видите пример Кварца 2D получение к представлению Cocoa путем рассмотрения рисунка 2-1. Получение состоит из двух перекрывающихся прямоугольников, непрозрачного красного и частично прозрачного синего. Вы узнаете больше о прозрачности в цвете и Цветовых пространствах. Возможность управлять, сколько можно “видеть через” цвета, является одной из функций признака 2D Кварца.

Рисунок 2-1  представление в платформе Какао, содержащей Кварцевое получение
A view in the Cocoa framework that contains Quartz drawing

Для создания получения на рисунке 2-1 Вы сначала создаете приложение Какао проект XCode. В Интерфейсном Разработчике перетащите Пользовательское Представление к окну и разделите его на подклассы. Тогда запишите реализацию для разделенного на подклассы представления, подобного тому, что показывает Перечисление 2-1. Для этого примера называют разделенное на подклассы представление MyQuartzView. drawRect: метод для представления содержит весь Кварцевый код для прорисовки. Подробное объяснение каждой пронумерованной строки кода появляется после перечисления.

  Получение перечисления 2-1 к контексту графики окна

@implementation MyQuartzView
 
- (id)initWithFrame:(NSRect)frameRect
{
    self = [super initWithFrame:frameRect];
    return self;
}
 
- (void)drawRect:(NSRect)rect
{
    CGContextRef myContext = [[NSGraphicsContext // 1
                                currentContext] graphicsPort];
   // ********** Your drawing code here ********** // 2
    CGContextSetRGBFillColor (myContext, 1, 0, 0, 1);// 3
    CGContextFillRect (myContext, CGRectMake (0, 0, 200, 100 ));// 4
    CGContextSetRGBFillColor (myContext, 0, 0, 1, .5);// 5
    CGContextFillRect (myContext, CGRectMake (0, 0, 100, 200));// 6
  }
 
@end

Вот то, что делает код:

  1. Получает графический контекст для представления.

  2. Это - то, где Вы вставляете свой код для прорисовки. Четыре следующие строки кода являются примерами использования Кварца 2D функции.

  3. Устанавливает красный цвет заливки, это полностью непрозрачно. Для получения информации о цветах и альфе (который устанавливает непрозрачность), посмотрите Цветовые и Цветовые пространства.

  4. Заполняет прямоугольник, источник которого (0,0) и чья ширина 200 и высота 100. Для получения информации о рисовании прямоугольников посмотрите Пути.

  5. Устанавливает синий цвет заливки, это частично прозрачно.

  6. Заполняет прямоугольник, источник которого (0,0) и чья ширина 100 и высота 200.

Создание контекста графики PDF

Когда Вы создаете контекст графики PDF и рисуете к тому контексту, Кварц записывает Ваше получение как ряд команд рисования PDF, записанных в файл. Вы предоставляете расположение для вывода PDF и поля носителей по умолчанию — прямоугольник, указывающий границы страницы. Рисунок 2-2 показывает результат рисования к контексту графики PDF и затем открытию получающегося PDF в Предварительном просмотре.

Рисунок 2-2  PDF создается при помощи CGPDFContextCreateWithURL
A PDF created by using CGPDFContextCreateWithURL

2D API Кварца обеспечивает две функции, создающие контекст графики PDF:

Подробное объяснение каждой пронумерованной строки кода следует за каждым перечислением.

  Вызов перечисления 2-2 CGPDFContextCreateWithURL создать контекст графики PDF

CGContextRef MyPDFContextCreate (const CGRect *inMediaBox,
                                    CFStringRef path)
{
    CGContextRef myOutContext = NULL;
    CFURLRef url;
 
    url = CFURLCreateWithFileSystemPath (NULL, // 1
                                path,
                                kCFURLPOSIXPathStyle,
                                false);
    if (url != NULL) {
        myOutContext = CGPDFContextCreateWithURL (url,// 2
                                        inMediaBox,
                                        NULL);
        CFRelease(url);// 3
    }
    return myOutContext;// 4
}

Вот то, что делает код:

  1. Вызывает Базовую функцию Основы для создания объекта CFURL из объекта CFString, предоставленного MyPDFContextCreate функция. Вы передаете NULL как первый параметр, который будет использовать средство выделения по умолчанию. Также необходимо указать стиль пути, который для этого примера является путем стиля POSIX.

  2. Вызывает Кварц 2D функция для создания контекста графики PDF с помощью расположения PDF, просто созданного (как объект CFURL) и прямоугольник, указывающий границы PDF. Прямоугольник (CGRect) был передан MyPDFContextCreate функционируйте и ограничительная рамка носителей страницы по умолчанию для PDF.

  3. Выпускает объект CFURL.

  4. Возвращает контекст графики PDF. Вызывающая сторона должна выпустить графический контекст, когда это больше не необходимо.

  Вызов перечисления 2-3 CGPDFContextCreate создать контекст графики PDF

CGContextRef MyPDFContextCreate (const CGRect *inMediaBox,
                                    CFStringRef path)
{
    CGContextRef        myOutContext = NULL;
    CFURLRef            url;
    CGDataConsumerRef   dataConsumer;
 
    url = CFURLCreateWithFileSystemPath (NULL, // 1
                                        path,
                                        kCFURLPOSIXPathStyle,
                                        false);
 
    if (url != NULL)
    {
        dataConsumer = CGDataConsumerCreateWithURL (url);// 2
        if (dataConsumer != NULL)
        {
            myOutContext = CGPDFContextCreate (dataConsumer, // 3
                                        inMediaBox,
                                        NULL);
            CGDataConsumerRelease (dataConsumer);// 4
        }
        CFRelease(url);// 5
    }
    return myOutContext;// 6
}

Вот то, что делает код:

  1. Вызывает Базовую функцию Основы для создания объекта CFURL из объекта CFString, предоставленного MyPDFContextCreate функция. Вы передаете NULL как первый параметр, который будет использовать средство выделения по умолчанию. Также необходимо указать стиль пути, который для этого примера является путем стиля POSIX.

  2. Создает Кварцевый потребительский объект данных использование объекта CFURL. Если Вы не хотите использовать объект CFURL (например, Вы хотите поместить данные PDF в расположение, которое не может быть указано объектом CFURL), можно вместо этого создать потребителя данных из ряда функций обратного вызова, которые Вы реализуете в своем приложении. Для получения дополнительной информации посмотрите управление данными в 2D Кварце.

  3. Вызывает Кварц 2D функция для создания контекста графики PDF, передающего как параметры потребитель данных и прямоугольник (типа CGRect) это было передано MyPDFContextCreate функция. Этот прямоугольник является ограничительной рамкой носителей страницы по умолчанию для PDF.

  4. Выпускает потребителя данных.

  5. Выпускает объект CFURL.

  6. Возвращает контекст графики PDF. Вызывающая сторона должна выпустить графический контекст, когда это больше не необходимо.

Перечисление 2-4 показывает, как вызвать MyPDFContextCreate подпрограмма и рисует к нему. Подробное объяснение каждой пронумерованной строки кода появляется после перечисления.

  Получение перечисления 2-4 к контексту графики PDF

    CGRect mediaBox;// 1
 
    mediaBox = CGRectMake (0, 0, myPageWidth, myPageHeight);// 2
    myPDFContext = MyPDFContextCreate (&mediaBox, CFSTR("test.pdf"));// 3
 
    CFStringRef myKeys[1];// 4
    CFTypeRef myValues[1];
    myKeys[0] = kCGPDFContextMediaBox;
    myValues[0] = (CFTypeRef) CFDataCreate(NULL,(const UInt8 *)&mediaBox, sizeof (CGRect));
    CFDictionaryRef pageDictionary = CFDictionaryCreate(NULL, (const void **) myKeys,
                                                        (const void **) myValues, 1,
                                                        &kCFTypeDictionaryKeyCallBacks,
                                                        & kCFTypeDictionaryValueCallBacks);
    CGPDFContextBeginPage(myPDFContext, &pageDictionary);// 5
        // ********** Your drawing code here **********// 6
        CGContextSetRGBFillColor (myPDFContext, 1, 0, 0, 1);
        CGContextFillRect (myPDFContext, CGRectMake (0, 0, 200, 100 ));
        CGContextSetRGBFillColor (myPDFContext, 0, 0, 1, .5);
        CGContextFillRect (myPDFContext, CGRectMake (0, 0, 100, 200 ));
    CGPDFContextEndPage(myPDFContext);// 7
    CFRelease(pageDictionary);// 8
    CFRelease(myValues[0]);
    CGContextRelease(myPDFContext);

Вот то, что делает код:

  1. Объявляет переменную для прямоугольника, который Вы используете для определения поля носителей PDF.

  2. Устанавливает источник поля носителей к (0,0) и ширина и высота к переменным предоставляются приложением.

  3. Вызывает функцию MyPDFContextCreate (См. Перечисление 2-3) получить контекст графики PDF, предоставляя поле носителей и путь. Макрос CFSTR преобразовывает строку в a CFStringRef тип данных.

  4. Устанавливает словарь с опциями страницы. В этом примере только указано поле носителей. Вы не должны передавать тот же прямоугольник, Вы раньше устанавливали контекст графики PDF. Поле носителей, которое Вы добавляете здесь, заменяет прямоугольник, который Вы передаете для установки контекста графики PDF.

  5. Сигнализирует запуск страницы. Эта функция используется для ориентированной на страницу графики, которая является, каково получение PDF.

  6. Кварц вызовов 2D функции получения. Вы заменяете это и следующие четыре строки кода с кодом для прорисовки, подходящим для Вашего приложения.

  7. Сигнализирует конец страницы PDF.

  8. Выпускает словарь и контекст графики PDF, когда они больше не необходимы.

Можно записать любое содержание в PDF, это подходяще для приложения — изображений, текста, получения пути — и можно добавить ссылки и шифрование. Для получения дополнительной информации посмотрите Создание Документа в формате PDF, Просмотр и Преобразование.

Создание контекста растрового изображения

Контекст растрового изображения принимает указатель на буфер памяти, содержащий пространство памяти для битового массива. Когда Вы красите в контекст растрового изображения, буфер обновляется. После выпуска графического контекста у Вас есть полностью обновленный битовый массив в формате пикселя, который Вы указываете.

Вы используете функцию CGBitmapContextCreate создать контекст растрового изображения. Эта функция берет следующие параметры:

Перечисление 2-5 показывает, как создать контекст растрового изображения. Когда Вы вовлекаете контекст графики полученного растрового изображения, Кварц записывает Ваше получение как растровые данные в указанном блоке памяти. Подробное объяснение каждой пронумерованной строки кода следует за перечислением.

Перечисление 2-5  , Создающее контекст растрового изображения

CGContextRef MyCreateBitmapContext (int pixelsWide,
                            int pixelsHigh)
{
    CGContextRef    context = NULL;
    CGColorSpaceRef colorSpace;
    void *          bitmapData;
    int             bitmapByteCount;
    int             bitmapBytesPerRow;
 
    bitmapBytesPerRow   = (pixelsWide * 4);// 1
    bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);
 
    colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);// 2
    bitmapData = calloc( bitmapByteCount );// 3
    if (bitmapData == NULL)
    {
        fprintf (stderr, "Memory not allocated!");
        return NULL;
    }
    context = CGBitmapContextCreate (bitmapData,// 4
                                    pixelsWide,
                                    pixelsHigh,
                                    8,      // bits per component
                                    bitmapBytesPerRow,
                                    colorSpace,
                                    kCGImageAlphaPremultipliedLast);
    if (context== NULL)
    {
        free (bitmapData);// 5
        fprintf (stderr, "Context not created!");
        return NULL;
    }
    CGColorSpaceRelease( colorSpace );// 6
 
    return context;// 7
}

Вот то, что делает код:

  1. Объявляет, что переменная представляет число байтов на строку. Каждый пиксель в битовом массиве в этом примере представлен на 4 байта; 8 битов каждый красный, зеленый, синий цвет, и альфа.

  2. Создает универсальное цветовое пространство RGB. Можно также создать цветовое пространство CMYK. Посмотрите Цветовые и Цветовые пространства для получения дополнительной информации и для обсуждения универсальных цветовых пространств по сравнению с зависимыми от устройств.

  3. Вызовы calloc функция, чтобы создать и очистить блок памяти, в которой можно хранить растровые данные. Этот пример создает 32-разрядный битовый массив RGBA (т.е. массив с 32 битами на пиксель, каждый пиксель, содержащий 8 битов каждый красный, зеленый, синий цвет, и информация об альфе). Каждый пиксель в битовом массиве занимает 4 байта памяти. Если Вы передаете, в Mac OS X 10.6 и iOS 4, этот шаг может быть опущен — NULL как растровые данные, Кварц автоматически выделяет площадь для битового массива.

  4. Создает контекст растрового изображения, снабжая растровыми данными, шириной и высотой битового массива, числом битов на компонент, байтов на строку, цветовое пространство и константу, указывающую, должен ли битовый массив содержать альфа-канал и его относительное расположение в пикселе. Константа kCGImageAlphaPremultipliedLast указывает, что альфа-компонент сохранен в последнем байте каждого пикселя и что компоненты цвета были уже умножены на это альфа-значение. Посмотрите Альфа-Значение для получения дополнительной информации о предварительно умноженной альфе.

  5. Если контекст не создается по некоторым причинам, освобождает память, выделенную для растровых данных.

  6. Освобождает цветовое пространство.

  7. Возвращает контекст растрового изображения. Вызывающая сторона должна выпустить графический контекст, когда это больше не необходимо.

Перечисление 2-6 показывает вызывающий код MyCreateBitmapContext для создания контекста растрового изображения, использует контекст растрового изображения для создания a CGImage объект, затем рисует получающееся изображение к контексту графики окна. Рисунок 2-3 показывает изображение, нарисованное окну. Подробное объяснение каждой пронумерованной строки кода следует за перечислением.

  Получение перечисления 2-6 к контексту растрового изображения

    CGRect myBoundingBox;// 1
 
    myBoundingBox = CGRectMake (0, 0, myWidth, myHeight);// 2
    myBitmapContext = MyCreateBitmapContext (400, 300);// 3
    // ********** Your drawing code here ********** // 4
    CGContextSetRGBFillColor (myBitmapContext, 1, 0, 0, 1);
    CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 200, 100 ));
    CGContextSetRGBFillColor (myBitmapContext, 0, 0, 1, .5);
    CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 100, 200 ));
    myImage = CGBitmapContextCreateImage (myBitmapContext);// 5
    CGContextDrawImage(myContext, myBoundingBox, myImage);// 6
    char *bitmapData = CGBitmapContextGetData(myBitmapContext); // 7
    CGContextRelease (myBitmapContext);// 8
    if (bitmapData) free(bitmapData); // 9
    CGImageRelease(myImage);// 10

Вот то, что делает код:

  1. Объявляет, что переменная хранит источник и размерности ограничительной рамки, в которую Кварц нарисует изображение, создаваемое из контекста растрового изображения.

  2. Устанавливает источник ограничительной рамки к (0,0) и ширина и высота к переменным, ранее объявленным, но чье объявление не показано в этом коде.

  3. Вызывает предоставленную приложение функцию MyCreateBitmapContext (см. Перечисление 2-5) создать растровый контекст, который 400 пикселей шириной и 300 пикселей высотой. Можно создать контекст растрового изображения с помощью любых размерностей, которые являются подходящими для приложения.

  4. Кварц вызовов 2D функции для вовлечения контекста растрового изображения. Вы заменили бы это и следующие четыре строки кода с кодом для прорисовки, подходящим для Вашего приложения.

  5. Создает Кварц 2D изображение (CGImageRef) от контекста растрового изображения.

  6. Вовлекает изображение в расположение в контексте графики окна, указанном ограничительной рамкой. Ограничительная рамка указывает расположение и размерности в пространстве пользователя, в котором можно нарисовать изображение.

    Этот пример не показывает создание контекста графики окна. Посмотрите Создание Контекста Графики Окна в Mac OS X для получения информации о том, как создать тот.

  7. Связали растровые данные с контекстом растрового изображения.

  8. Выпускает контекст растрового изображения, когда он больше не необходим.

  9. Освободите растровые данные, если они существуют.

  10. Выпускает изображение, когда оно больше не необходимо.

Рисунок 2-3  изображение, создаваемое из контекста растрового изображения и нарисованное к контексту графики окна
An image created from a bitmap graphics context and drawn to a window graphics context

Поддерживаемые форматы пикселя

Таблица 2-1 суммирует форматы пикселя, поддерживающиеся для контекста растрового изображения, связанное цветовое пространство (cs), и версия Mac OS X, в котором формат был сначала доступен. Формат пикселя указан как биты на пиксель (бит/пкс) и биты на компонент (bpc). Таблица также включает растровую информацию, постоянную связанный с тем форматом пикселя. См. Ссылку CGImage для подробных данных о том, что каждую из констант формата растровой информации представляют.

Табличные 2-1  Форматы пикселя поддерживаются для контекстов растрового изображения

CS

Формат пикселя и постоянная растровая информация

Доступность

Нуль

8 бит/пкс, 8 bpc, kCGImageAlphaOnly

Mac OS X, iOS

Серый

8 бит/пкс, 8 bpc,kCGImageAlphaNone

Mac OS X, iOS

Серый

8 бит/пкс, 8 bpc,kCGImageAlphaOnly

Mac OS X, iOS

Серый

16 бит/пкс, 16 bpc, kCGImageAlphaNone

Mac OS X

Серый

32 бит/пкс, 32 bpc, kCGImageAlphaNone|kCGBitmapFloatComponents

Mac OS X

RGB

16 бит/пкс, 5 bpc, kCGImageAlphaNoneSkipFirst

Mac OS X, iOS

RGB

32 бит/пкс, 8 bpc, kCGImageAlphaNoneSkipFirst

Mac OS X, iOS

RGB

32 бит/пкс, 8 bpc, kCGImageAlphaNoneSkipLast

Mac OS X, iOS

RGB

32 бит/пкс, 8 bpc, kCGImageAlphaPremultipliedFirst

Mac OS X, iOS

RGB

32 бит/пкс, 8 bpc, kCGImageAlphaPremultipliedLast

Mac OS X, iOS

RGB

64 бит/пкс, 16 bpc, kCGImageAlphaPremultipliedLast

Mac OS X

RGB

64 бит/пкс, 16 bpc, kCGImageAlphaNoneSkipLast

Mac OS X

RGB

128 бит/пкс, 32 bpc, kCGImageAlphaNoneSkipLast |kCGBitmapFloatComponents

Mac OS X

RGB

128 бит/пкс, 32 bpc, kCGImageAlphaPremultipliedLast |kCGBitmapFloatComponents

Mac OS X

CMYK

32 бит/пкс, 8 bpc, kCGImageAlphaNone

Mac OS X

CMYK

64 бит/пкс, 16 bpc, kCGImageAlphaNone

Mac OS X

CMYK

128 бит/пкс, 32 bpc, kCGImageAlphaNone |kCGBitmapFloatComponents

Mac OS X

Сглаживание

Сглаживание поддержки контекстов растрового изображения, которое является процессом искусственного исправления зубчатого (или искаженный) ограничивает Вас, иногда видят в растровых изображениях, когда составлены текст или формы. Когда разрешение битового массива значительно ниже, чем разрешение Ваших глаз, эти зубчатые края происходят. Чтобы заставить объекты казаться гладкими в битовом массиве, Кварц использует различные цвета для пикселей, окружающих схему формы. Путем смешивания цветов таким образом, форма кажется гладкой. Вы видите эффект использования сглаживания на рисунке 2-4. Можно выключить сглаживание для определенного контекста растрового изображения путем вызывания функции CGContextSetShouldAntialias. Настройка сглаживания является частью состояния графики.

Можно управлять, позволить ли сглаживаться для определенного графического контекста при помощи функции CGContextSetAllowsAntialiasing. Передача true к этой функции, чтобы позволить сглаживаться; false не позволить его. Эта установка не является частью состояния графики. Когда контекст и графические настройки состояния установлены в, кварц выполняет сглаживание true.

Рисунок 2-4  сравнение искаженного и сглаживающегося получения
A comparison of aliased and anti-aliasing drawing

Получение графического контекста для печати

Приложения какао в печати реализации Mac OS X через пользовательский NSView подклассы. Представлению говорят распечатать путем вызова print: метод. Представление тогда создает графический контекст, предназначающийся для принтера и вызывающий drawRect: метод. Ваше приложение использует тот же код для прорисовки для рисования к принтеру, который это использует для рисования на экран. Это может также настроить drawRect: вызовите к изображению к принтеру, отличающемуся от того, отправленного в экран.

Для детального обсуждения печати в Какао см. Руководство по программированию Печати для Mac.