Главная » Разработка для Android » Извлечение максимальной пользы из объекта Paint

0

Класс Paint представляет собой сочетание кисти и палитры. Он позво- ляет выбирать способ отображения графических примитивов, которые вы рисуете на объекте Canvas с помощью методов, описанных в предыдущем разделе. Изменяя объект Paint,  можно контролировать цвет, стиль, шрифт и специальные эффекты,  используемые при рисовании.

Метод setColor  позволяет  выбрать цвет кисти, стиль объекта Paint (за- даваемый с помощью метода setStyle) — рисовать либо очертания графиче- ского примитива (STROKE), либо его заливку  (FILL), либо и то, и другое сразу (STROKE_AND_FILL).

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

Android SDK включает в себя проекты, предоставляющие большую часть возможностей класса Paint.  Они доступны  в подкаталоге  graphics  наряду с другими приложениями, демонстрирующими различные API:

[корневой каталог sdk]\samples\ApiDemos\src\com\android\samples\graphics

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

Использование  полупрозрачности.  Любой  цвет в Android  содержит свойство прозрачности (альфа-канал).

Указать  его можно при создании  описывающей цвет переменной,  ис- пользуя методы argb и parseColor:

// Сделайте цвет красным и наполовину прозрачным int opacity = 127;

int intColor = Color.argb(opacity, 255, 0, 0);

int parsedColor = Color.parseColor("#7FFF0000");

Как вариант, можете задать прозрачность уже существующего  объекта

Paint с помощью метода setAlpha:

// Сделайте цвет наполовину прозрачным int opacity = 127; myPaint.setAlpha(opacity);

Создание цвета, непрозрачность которого менее 100 %, означает, что лю- бой графический примитив, нарисованный с его помощью, станет частично прозрачным:  в какой-то мере будет видно все, что нарисовано  под ним.

Вы можете использовать эффект прозрачности в любом классе или ме- тоде, которые работают с цветом, включая Paint,  Shader, MaskFilter.

Знакомство с шейдерами. Расширения класса Shader  позволяют  соз- давать объекты Paint,  которые закрашивают элементы более сложным об- разом, чем просто заливка сплошным цветом.

Наиболее  часто шейдеры используются для описания  градиентной  за- ливки. При помощи градиентов вы можете легко придать двумерному  ри- сунку глубину и фактуру. Android поддерживает три градиентных шейдера (помимо растровых и композитных).

Описывать методики рисования словами — занятие  бессмысленное по своей сути, поэтому лучше взгляните на рис. 15.1, чтобы понять принцип работы каждого из этих шейдеров. Слева направо представлен результат работы классов LinearGradient, RadialGradient и SweepGradient.

ПРИМЕЧАНИЕ

На рис. 15.1 не представлены классы ComposeShader и BitmapShader. С помощью первого вы можете смешивать разные шейдеры, второй позволяет создавать кисти для рисования, основанные на растровых изображениях.

Чтобы  использовать шейдеры  при рисовании,  их нужно  применять к объекту Paint с помощью метода setShader:

Paint shaderPaint = new Paint();

shaderPaint.setShader(myLinearGradient);

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

Задание  градиентных шейдеров.  Как говорилось  в предыдущих  раз- делах, градиентные  шейдеры позволяют  закрашивать контуры с помощью интерполированной цветовой гаммы. Вы можете задать градиент двумя способами.

Первый  — простой  переход между двумя цветами, как показано  в ли- стинге 15.19 на примере класса LinearGradientShader.

Листинг 15.19. Создание линейного  градиента

int colorFrom = Color.BLACK;

int colorTo = Color.WHITE;

LinearGradient linearGradientShader = new LinearGradient(x1, y1, x2, y2, colorFrom, colorTo, TileMode.CLAMP);

Второй способ, продемонстрированный в листинге 15.20, предусматри- вает описание более сложных последовательностей цветов, распределенных в заданных пропорциях.

Листинг 15.20. Создание радиального  градиента

int[] gradientColors = new int[3]; gradientColors[0] = Color.GREEN; gradientColors[1] = Color.YELLOW; gradientColors[2] = Color.RED;

float[] gradientPositions = new float[3];

gradientPositions[0] = 0.0f;

gradientPositions[1] = 0.5f; gradientPositions[2] = 1.0f;

RadialGradient radialGradientShader = new RadialGradient(centerX, centerY, radius, gradientColors, gradientPositions, TileMode.CLAMP);

Каждый  из градиентных  шейдеров  (линейный, радиальный и развер- нутый)  позволяет  задать градиентную  заливку,  используя любой из при- веденных выше способов.

Использование режимов заполнения в шейдерах. Размеры  кисти для градиентных  шейдеров  определяются с помощью явно заданных  прямо- угольных границ или с использованием сочетания центральной точки и дли- ны радиуса. В растровых  шейдерах размер кисти равен размерам  изобра- жения.

Если область, заданная кистью шейдера, меньше, чем область для запол- нения, режим TileMode  определяет,  каким образом заполнится остальная площадь.

CLAMP. Использует цвета по краям шейдера для заполнения допол- нительного  пространства.

MIRROR. Отображает изображение шейдера по горизонтали и вер- тикали таким образом, чтобы каждая следующая часть соприкасалась с предыдущей.

REPEAT. Повторяет изображение шейдера по горизонтали и верти- кали, но не отображает его.

Использование  фильтров для масок. Класс MaskFilter позволяет  на- значать  контурные  эффекты для объекта Paint.  Классы, наследующие MaskFilter, применяют преобразования к альфа-каналу объекта Paint вдоль его внешней границы.

Android включает следующие фильтры  для масок:

BlurMaskFilter — задает стиль размытия и радиус выступов для краев объекта Paint;

EmbossMaskFilter — задает направление источника  света и уровень освещенности, создавая эффект  рельефа.

Чтобы применить  фильтр  для маски, используйте метод setMaskFilter, передавая  ему в качестве  параметра  объект MaskFilter. В листинге  15.21 показан процесс наложения фильтра EmbossMaskFilter на имеющийся объ- ект Paint.

Листинг 15.21. Применение фильтра  EmbossMaskFilter к объекту Paint

// Задайте направление источника света float[] direction = new float[]{ 1, 1, 1 };

// Установите уровень освещенности float light = 0.4f;

// Выберите степень зеркальности float specular = 6;

// Укажите, какой уровень размытия должен применяться к маске float blur = 3.5f;

EmbossMaskFilter emboss = new EmbossMaskFilter(direction, light, specular, blur);

// Примените маску

myPaint.setMaskFilter(emboss);

Демонстрационный проект FingerPaint, входящий в состав SDK, — от- личный пример использования объектов MaskFilter. Он демонстрирует оба эффекта  — BlurMaskFilter и EmbossMaskFilter.

Использование цветовых фильтров. В отличие от фильтров для масок, которые преобразуют альфа-канал объекта Paint, цветовые фильтры затра- гивают каждый из каналов RGB. Все потомки класса ColorFilter игнорируют альфа-канал во время преобразований.

Android содержит три цветовых фильтра.

ColorMatrixColorFilter. Позволяет задать для объекта Paint матрицу ColorMatrix размером 4 x 5. Объекты  ColorMatrix, как правило,  ис- пользуются  при программной  обработке изображений, могут приго- диться также для последовательных преобразований с применением умножения матриц.

LightingColorFilter. Умножает  каналы  RGB первого цвета, прежде чем добавить второй. Результат каждого преобразования варьируется от 0 до 255.

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

Использовать цветовые фильтры  можно, задействовав для этого метод setColorFilter:

myPaint.setColorFilter(new LightingColorFilter(Color.BLUE, Color.RED));

В каталоге  с примерами  вы найдете приложение под названием  Co- lorMatrixSample, которое демонстрирует работу цветовых  фильтров и ма- триц.

Использование  контурных эффектов. До сих пор рассматривались эффекты, которые влияли на способ заливки рисунка. Контурные эффекты используются для управления отрисовкой  контура. Они чрезвычайно по- лезны для рисования контурных  графических примитивов, но могут быть применены  к любому объекту Paint,  чтобы повлиять на способ отрисовки их очертаний.

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

CornerPathEffect. Позволяет сглаживать острые углы в форме графи- ческого примитива,  заменяя  их на закругленные.

DashPathEffect. Вместо рисования сплошного  контура  можете ис- пользовать  DashPathEffect для создания  очертания,  состоящего  из ломаных  линий  (тире/точек). Есть возможность указать любой ша- блон повторения сплошных/пустых отрезков.

DiscretePathEffect. Делает то же самое, что и DashPathEffect, но до- бавляет  элемент  случайности.  Указываются длина каждого отрезка и степень отклонения от оригинального контура.

PathDashPathEffect. Позволяет определить  новую фигуру  (контур), чтобы использовать ее в виде отпечатка оригинального контура.

Следующие классы помогают сочетать различные контурные эффекты в контексте единственного объекта Paint:

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

ComposePathEffect — использует первый эффект, затем к полученно- му результату добавляет второй.

Контурные эффекты, влияющие на форму объекта, который должен быть нарисован,  изменяют  и область, занимаемую  им. Благодаря этому любые эффекты для закрашивания, применяемые к данной фигуре, отрисовыва- ются в новых границах.

Контурные  эффекты применяются к объекту Paint с помощью метода setPathEffect:

borderPaint.setPathEffect(new CornerPathEffect(5));

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

Изменение  режима Xfermode. Изменение режима Xfermode для объ- екта Paint влияет  на способ наложения новых цветов поверх уже нарисо- ванных.

В обычных обстоятельствах при рисовании поверх имеющегося рисунка создастся новый верхний слой. Если новый объект Paint на 100 % непрозрач- ный, он полностью закрасит все, что находится под областью для рисования; если он полупрозрачный, то только затенит лежащие ниже цвета.

Подклассы  Xfermode позволяют  изменить  такое поведение.

AvoidXfermode. Определяет цвет, поверх которого объект Paint не мо- жет (или  наоборот — может только поверх него) рисовать. Задается также параметр tolerance,  указывающий на допустимое отклонение.

PixelXorXfermode. Применяет простое побитовое исключение (XOR)

при рисовании поверх существующих цветов.

PorterDuffXfermode. Мощный  режим, с помощью которого  можно использовать любое из шестнадцати  правил смешивания изображе- ний Портера-Даффа, управляя процессом  наложения кисти на уже существующий рисунок.

Для того чтобы применить  один из этих режимов,  используйте метод setXferMode:

AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode.AVOID);

borderPen.setXfermode(avoid);

Источник: Майер P. Android 2 : программирование приложений для планшетных компьютеров и смартфонов : [пер. с англ. ] / Рето Майер. — М. : Эксмо, 2011. — 672 с. — (Мировой компьютерный бестселлер).

По теме:

  • Комментарии