Клас 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 ();
Все, що ви намалюєте із застосуванням цієї кисті, буде зафарбовувати зазначеним шейдером, замість суцільного кольору.
Завдання градієнтних шейдеров. Як говорилося в попередніх роз- ділах, градієнтні шейдери дозволяють зафарбовувати контури за допомогою інтерпольованої колірної гами. Ви можете задати градієнт двома способами.
Перший - простий перехід між двома квітами, як показано в ли- Стінг 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 [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);
Демонстраційний проект 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:
У каталозі з прикладами ви можете знайти керівництво для роботи з каж дим з описаних вище ефектів.
Зміна режиму Xfermode. Зміна режиму Xfermode для об'єк єкта Paint впливає на спосіб накладення нових кольорів поверх вже нарісо- ванних.
У звичайних обставинах при малюванні поверх наявного малюнка створиться новий верхній шар. Якщо новий об'єкт Paint на 100% непрозрач- ний, він повністю зафарбувати все, що знаходиться під областю для малювання; якщо він напівпрозорий, то тільки затенит лежать нижче кольори.
Підкласи Xfermode дозволяють змінити таку поведінку.
• AvoidXfermode. Визначає колір, поверх якого об'єкт Paint не може (або навпаки - може тільки поверх нього) малювати. Здається також параметр tolerance, який вказує на допустиме відхилення.
• PixelXorXfermode. Застосовує просте побітовое виняток (XOR)
при малюванні поверх існуючих квітів.
• PorterDuffXfermode. Потужний режим, за допомогою якого можна використовувати будь-який з шістнадцяти правил змішування ізображе- ний Портера-Даффа, керуючи процесом накладення кисті на вже існуючий малюнок.
Для того щоб застосувати один з цих режимів, використовуйте метод setXferMode:
AvoidXfermode avoid = new AvoidXfermode (Color.BLUE, 10, AvoidXfermode.Mode.AVOID);