C# для профессионалов. Том II - Симон Робинсон
Шрифт:
Интервал:
Закладка:
Теперь можно понять, откуда появляется число 16777216, оно равно 256 в кубе.
Это дает нам первый способ задания цвета в GDI+. Можно указать значения для красного, синего и зеленого цветов, вызывая статическую функцию Color.FromArgb(). Компания Microsoft решила не поставлять конструктор для этой задачи. Причина в том, что существуют другие способы, помимо обычных компонентов RGB, для указания конструктора. В связи с этим Microsoft решила, что значения параметров, передаваемых в любой конструктор, будет подвержено неверной интерпретации:
Color RedColor = Color.FromArgb(255, 0, 0);
Color FunnyOrangyBrownColor = Color.FromArgb(255, 155, 100);
Color BlackColor = Color.FromArgb(0, 0, 0);
Color WhiteColor = Color.FromArgb(255, 255, 255);
Три параметра являются соответственно количествами красного, синего и зеленого цвета. Существует ряд других перегружаемых методов для этой функции, некоторые из них также позволяют определить так называемую альфа-смесь (отсюда буква А в названии метода FromArgb()!). Альфа-смешивание не рассматривается в этой главе, оно позволяет рисовать полупрозрачными тонами, комбинируя с цветом, который уже имеется на экране. Это может создавать красивые эффекты и часто используется в играх.
Именованные цвета
Создание структуры Color с помощью FromArgb() является наиболее гибкой техникой, так как она по сути означает, что можно определить любой цвет, который различает человеческий глаз. Однако, если требуется простой, стандартный, хорошо известный цвет, такой как красный или синий, то значительно легче просто назвать требуемый цвет. В связи с этим Microsoft предоставляет также большое число статических свойств в Color, каждое из которых возвращает именованный цвет. Одно из этих свойств использовалось, когда в примерах задавался фоновый цвет окон как белый:
this.BackColor = Color.White;
// имеет такой же эффект, как и
// this.BackColor = Color.FromArgb(255, 255, 255);
Существует несколько сотен таких цветов. Полный список дан в документации MSDN. Он включает все простые цвета: Red, White, Blue, Green, Black и т.д., а также такие, как MediumAquamarine, LightCoral и DarkOrchid.
В связи с этим такие именованные цвета были выбраны не случайно. Каждый из них представляет определенный набор значений RGB, и они были первоначально выбраны много лет назад для использования в Интернете. Идея состояла в том, чтобы предоставить полезный набор цветов по всему спектру, имена которых будут распознаваться браузерами Web, таким образом позволяя избежать написания явных значений RGB в коде HTML. Несколько лет назад эти цвета были очень важны, так как ранние браузеры не могли точно воспроизводить многие цвета и именованные цвета, правильно выводимые большинством браузеров, предназначались для обеспечения множества цветов. Сегодня этот аспект не имеет решающего значения, так как современные браузеры Web вполне способны вывести правильно любое значение RGB.
Режимы вывода графики и палитра безопасности
При том что в принципе мониторы могут вывести любой из 16 млн цветов RGB, на практике это зависит от того, как заданы свойства вывода изображения на компьютере. Делая щелчок правой кнопкой мыши на рабочем столе Windows и выбирая Settings в появляющейся таблице свойств, можно получить цветовое разрешение изображения. Здесь традиционно существует три основных варианта (хотя некоторые машины могут предоставлять другие возможности в зависимости от оборудования): true color (24-битовые), high color (16-битовые) и 256 цветов. (На некоторых графических платах сегодня true color в действительности помечены как 32-битовые с целью оптимизации аппаратного обеспечения, хотя в этом случае для самого цвета используются только 24 бита из 32).
Только режим true color позволяет выводить одновременно все цвета RGB. Это лучший вариант, но требует дополнительных расходов: для хранения полного значения RGB требуется 3 байта, т. е. для хранения каждого выводимого пикселя требуется 3 байта памяти графической платы. Если памяти графической платы достаточно (ограничение, которое встречается сегодня реже), то можно выбрать такой режим. Режим high color использует два байта на пиксель. Этого достаточно, чтобы задать 5 битов для каждой компоненты RGB. Поэтому вместо 256 градаций интенсивности красного, получается только 32 градации; то же самое для синего и зеленого, что дает всего 65536 цветов. Этого вполне достаточно, чтобы получить почти фотографическое качество при поверхностном рассмотрении, хотя области с легким затенением покажутся слегка неровными.
256-цветовой режим дает еще меньше цветов. Однако в этом режиме можно выбрать используемые цвета. В системе задается так называемая палитра. Это список 256 цветов, выбранных из 16 миллионов цветов RGB. После задания цветов в палитре графическое устройство может выводить только эти цвета. Палитра изменяется в любое время, но графическое устройство по-прежнему выведет только 256 различных цветов в данный момент времени. 256-цветный режим используется в действительности только, когда необходимо получить высокую производительность и при небольшом объеме видеопамяти. Большинство игр будут использовать этот режим, но за счет тщательного выбора палитры они по-прежнему смогут предоставить хорошее графическое оформление.
Вообще, если устройство вывода находится в режиме high color или 256 цветов и запрашивается для вывода определенного цвета RGB, то оно будет выбирать ближайшее математическое соответствие из пула доступных цветов. По этой причине важно знать о режимах цветов. При рисовании объекта, который содержит слабые затенения или имеет фотографическое качество, и если не выбран режим 24-битовых цветов, пользователь может не увидеть изображения в том виде, как это должно быть. Если работа такого рода делается с помощью GDI+, необходимо проверить приложение в различных режимах цветов. (Приложение может также программным путем задать цветовой режим, хотя этот вопрос здесь рассматриваться не будет).
Палитра безопасности
Для справки мы кратко упомянем здесь палитру безопасности. Это обычно палитра, используемая по умолчанию. Она работает так, что для каждого цветового компонента задается шесть расположенных на одинаковом расстоянии друг от друга возможных значений. А именно, значения 0, 51, 102, 153, 204, 255. Другими словами, красный компонент может иметь любое из этих значений. То же самое можно сказать о зеленом и синем компонентах. Поэтому возможные цвета из палитры безопасности включают (0, 0, 0) (черный), (153, 0, 0) (достаточно темный оттенок красного), (0, 255, 102) (зеленый с небольшой голубизной) и т. д. Это дает всего 6 в кубе = 216 цветов. Идея состоит в том, что это дает нам простой способ иметь палитру, которая содержит цвета из всего спектра и всех степеней яркости, хотя на практике это работает не так хорошо, так как равное математическое разделение цветовых компонентов не значит равного восприятия различия цветов человеческим глазом. Но поскольку палитра безопасности широко используется, можно найти большое число приложений и изображений, которые используют цвета исключительно из палитры безопасности.
При использовании 256-цветного режима Windows палитрой по умолчанию является палитра безопасности с добавленными 20 стандартными цветами Windows и 20 свободными цветами.
Перья и кисти
В этом разделе мы сделаем обзор двух вспомогательных классов, которые нужны для рисования фигур. Мы уже встречали класс Pen, используемый для сообщения экземпляру Graphics, как рисовать линии. Связанным является класс System.Drawing.Brush, который говорит, как заполнять области. Например, Pen требуется для рисования контуров прямоугольников и эллипсов в рассмотренных ранее примерах. Если понадобится нарисовать эти фигуры как заполненные, то для этого должна использоваться кисть, которая определяет, как заполнять фигуру. Одной из особенностей этих двух классов является то, что на них вряд-ли когда-нибудь будут вызываться какие-либо методы. Обычно просто создается экземпляр Pen или Brush с требуемым цветом и другими свойствами, а затем он передается в методы рисования.
Рассмотрим сначала кисти, а затем — перья.
Программисты, использовавшие ранее GDI, могут заметить из первых примеров, что перья используются в GDI+ другим способом. В GDI обычная практика состояла в вызове функции API Windows с именем SelectObject(), которая обычно связывает перо с контекстом устройства. Оно используется затем во всех операциях рисования, пока контекст устройства не будет связан с другим пером, снова вызывая метод SelectObject(). Тот же принцип сохраняется для кистей и других объектов, таких как шрифты или битовые изображения. С помощью GDI+, как упоминалось ранее, компания Microsoft перешла к модели без состояния, в которой нет пера по умолчанию или другого вспомогательного объекта. Вместо этого с каждым вызовом метода просто определяется подходящий вспомогательный объект, который будет использоваться для определенного метода.