Первая страница
Наша команда
Контакты
О нас

    Головна сторінка



Розрахунок витрат на розробку модифікованого алгоритму 77

Розрахунок витрат на розробку модифікованого алгоритму 77




Сторінка12/17
Дата конвертації16.03.2017
Розмір0.82 Mb.
1   ...   9   10   11   12   13   14   15   16   17

3.5 Реалізація графічної частини

Пакет android.graphics має всі необхідні бібліотеки для роботи з двомірної графікою. Існує декілька підходів для малювання графіки.

Для малювання простий графіки, яка не буде динамічно змінюватися під час роботи програми, зазвичай використовують клас, що успадковує від View і задіюють метод onDraw() [17].

У метод передається об'єкт Canvas, у якого є різні графічні методи.

Необов'язковий виклик методу requestWindowFeature (Window.FEATURE_NO_TITLE) використовується для створення екрану активності без заголовка. У методі setContentView() замість посилання на розмітку передається клас MyView, що успадковує від View. У методі onDraw() можете малювати.

У графіці важливу роль відіграє колір, який представлений класом android.graphics.Color. Клас Color містить кілька констант і методів для конвертації і вилучення колірного компонента.

Кольори можна описувати чотирма числами у форматі ARGB, по одному для кожного каналу (Alpha, Red, Green, Blue). Кожен з каналів є восьмібітним цілим числом, тобто може приймати значення від 0 до 256.

Константа (лат. constans - стала величина, інша назва - стала) - величина, що не змінює свого значення протягом певного процесу (на відміну від змінної, значення якої може змінюватись). Прикладами констант є число пі, коефіцієнти многочленів, температура під час ізотермічного процесу.

Ці́лі чи́сла - в математиці елементи множини Z = =\lbrace \ldots -3,\,-2,\,-1,\,0,\,1,\,2,\,3\,\ldots \rbrace } яка утворюється замиканням натуральних чисел відносно віднімання. Таким чином, цілі числа замкнуті відносно додавання, віднімання та множення.

Зазвичай колір упаковують в 32-бітове ціле число.

Ціле число (англ. Integer) - поширений тип даних, що представляє ціле число.

Варто відзначити, що використовувати цілі числа для кольорів ефективніше, ніж екземпляри класу Color.

Якщо всі значення RGB-каналів встановити рівними 0, то отримаємо чорний колір, якщо вибрати значення 255, то отримаємо білий колір.

Іноді значення вказуються не в десятковому формі, а в шістнадцятковому від 00 до FF, замість 0 і 255. У цьому випадку зазвичай пишуть не ARGB, а AARRGGBB. Наприклад, червоний колір в даному форматі буде дорівнювати FFFF0000 (AA = FF, RR = FF, GG = 00, BB = 00).

Для створення кольору можна використовувати статичні константи класу Color, наприклад Color.RED. Таких констант небагато, тільки для основних кольорів [18].

Статика - розділ механіки, в якому вивчають умови рівноваги нерухомих тіл.

Чо́рний ко́лір - ахроматичний колір, точніше - відсутність світлового потоку від об'єкта. Відтінки чорного кольору іменуються сірим кольором.

Черво́ний - колір з мінімальною частотою, що сприймається людським оком. Діапазон червоних кольорів в спектрі з довжиною хвилі 630–760 нанометрів, межа сприйняття залежить від віку. Один з трьох «основних» кольорів в системі RGB, додатковий колір до нього - синьо-зелений.

Бі́лий ко́лір - це ахроматичний колір, точніше зорова рівноважна сукупність усіх кольорів видимого спектру сонячного світла, сприймана людиною. Має найвищу яскравість, відтінок - 0. Білий колір може бути створений шляхом поєднання трьох основних кольорів - червоного, зеленого і синього (RGB-модель), або жовтого, пурпурного і блакитного (CMYK-модель) - у рівних концентраціях при найвищій яскравості.

Ко́лір (також ба́рва у контексті теми) - суб'єктивна характеристика сприйняття світлової хвилі, яка ґрунтується на здатності людського зору розрізняти електромагнітне випромінювання з довжиною хвиль в області видимого діапазону (видимий діапазон - довжини хвиль від 380 до 760 нм).

Отримати червону, зелену і синю складову кольору можна через методи red(), green(), blue(). Отримати потрібний колір з набору компонентів можна через методи rgb() і argb(), які повернуть вам int-значення кольору. Метод parseColor() дозволяє отримати int-значення з шістнадцяткової форми.

Краще задавати колір в ресурсах для більшої гнучкості. Завжди можна буде поміняти в разі необхідності без втручання в код програми. У коді можна звернутися до кольору наступним чином: color = getResources().getColor(R.color.mycolor). Окрім стандартної колірної моделі RGB використовується також колірна модель HSV.

Клас Paint містить стилі, кольори та іншу графічну інформацію для малювання графічних об'єктів. Він дозволяє вибирати спосіб відображення графічних примітивів, які ви малюєте на об'єкті Canvas за допомогою методів. Змінюючи об'єкт Paint, можна контролювати колір, стиль, шрифт і спеціальні ефекти, використовувані при малюванні. Наприклад, щоб встановити суцільний колір для малювання лінії, потрібно викликати метод Paint.setColor().

Метод setColor() дозволяє вибрати колір пензля, стиль об'єкта Paint (задається за допомогою методу setStyle) – малювати або обриси графічного примітиву (STROKE), або його заливку (FILL), або і те, й інше відразу (STROKE_AND_FILL).

Крім цих простих методів клас Paint підтримує прозорість і може бути змінений за допомогою різних шейдерів, фільтрів і ефектів, надає багатий набір складних фарб і пензлів.

Малювання графіки в об'єкті View використовується в тому випадку, якщо потрібно намалювати просту графіку, яка не буде динамічно змінюватися в процесі роботи програми, і не є реалізацією складної графічної гри [19].

Будь-який колір в Android містить властивість прозорості (альфа-канал). Вказати його можна при створенні описує колір змінної, використовуючи методи argb() і parseColor(). Але ми можемо задати прозорість вже існуючого об'єкта Paint за допомогою методу setAlpha().

Зміна режиму Xfermode для об'єкта Paint впливає на спосіб накладення нових кольорів поверх вже намальованих. У звичайних обставинах при малюванні поверх наявного малюнка створиться новий верхній шар. Якщо новий об'єкт Paint на 100% непрозорий, він повністю зафарбує все, що знаходиться під областю для малювання; якщо він напівпрозорий, то тільки затінить лежачі нижче кольори. Підкласи Xfermode дозволяють змінити таку поведінку.

Поведі́нка - родовий термін, який охоплює різні реакції живого організму чи групи організмів.

AvoidXfermode – визначає колір, поверх якого об'єкт Paint не може (або навпаки – може тільки поверх нього) малювати. Здається також параметр tolerance, який вказує на допустиме відхилення.

PixelXorXfermode – зстосовує просте побітовое виключення (XOR) при малюванні поверх існуючих кольорів.

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

Для того щоб застосувати один з цих режимів, використовуйте метод setXferMode()

При створенні нового об'єкта Paint ви можете передати в його конструктор кілька прапорів, які впливатимуть на спосіб відображення. Одним з найбільш цікавих з них вважається прапор ANTI_ALIAS_FLAG, що забезпечує згладжування діагональних ліній, змальованих об'єктом Paint (знижуючи при цьому продуктивність).

Згладжування відіграє важливу роль у процесі відтворення тексту, значно спрощує його сприйняття.

Сприйняття́, сприйма́ння (перцепція, від лат. perceptio) - пізнавальний психічний процес, який полягає у відображенні людиною предметів і явищ, у сукупності всіх їх якостей при безпосередній дії на органи чуття.

Щоб зробити текст ще більш гладким, можете використовувати прапор SUBPIXEL_TEXT_FLAG, який застосовує субпіксельне згладжування. Можна задати обидва цих прапора вручну, використовуючи методи setSubpixelText() і setAntiAlias().

Можна малювати не суцільними лініями, а пунктиром. Для цього є клас DashPathEffect.

Клас MaskFilter дозволяє призначати контурні ефекти для об'єкта Paint. Класи, що успадковують MaskFilter, застосовують перетворення до альфа-каналу об'єкта Paint уздовж його зовнішнього кордону.

Android включає наступні фільтри для масок:


  • EmbossMaskFilter – задає напрям джерела світла і рівень освітленості, створюючи ефект рельєфу;

    Джере́ла сві́тла - природні тіла або технічні пристрої різної конструкції і різними способами перетворення енергії, основним призначенням яких є отримання світлового випромінювання з різною довжиною хвилі, - як видимої частини спектру, так і невидимі для людського ока промені (наприклад, інфрачервоні).



  • BlurMaskFilter – задає стиль розмиття і радіус виступів для країв об'єкта Paint;

Щоб застосувати фільтр для маски, використовуйте метод setMaskFilter(), передаючи йому як параметр об'єкт MaskFilter.

Приклад використання EmbossMaskFilter зображено на рисунку 3.3.


embossmaskfilter

Рисунок 3.3 – Приклад роботи EmbossMaskFilter.


3.5.1 Canvas

Клас Canvas являє собою спеціальну поверхню (полотно), на якій ви можете малювати. За допомогою численних методів класу ви можете малювати лінії, кола, дуги і так далі [17, 20].

В Android екран захоплюється активністю, яка містить вікно перегляду View, яке в свою чергу містить полотно Canvas. Ви можете малювати на полотні, перевизначаючи метод View.OnDraw().

Малювання на полотні (Canvas) найкраще використовувати, коли вікно програми має регулярно себе перемальовувати під час роботи. Наприклад, при розробці ігор необхідно створювати постійно мінливу графіком. Всього існує два способи реалізації малювання на полотні:



  • в основному потоці програми, в якому запускається активність, ви створюєте власний компонент View, потім викликаєте метод invalidate() і обробляєте створення графіки в методі зворотного виклику onDraw();

  • в окремому потоці через об'єкт SurfaceView

Клас Canvas має власний набір методів для малювання: drawBitmap(), drawRect(), drawText() та інші. Деякі класи також мають методи draw(). Наприклад, можна створити об'єкти Drawable і передати їх для промальовування на полотно. Клас Drawable має власний метод draw(), який приймає об'єкт Canvas як параметр.

Полотно – це поверхня, на якій малюється ваша графіка. Коли ви виконуєте промальовування в межах методу зворотного виклику View.onDraw(), система передає в якості параметра об'єкт Canvas. Ви можете також отримати об'єкт Canvas викликом методу SurfaceHolder.lockCanvas(), якщо маєте справу з об'єктом SurfaceView.

Система викликає метод onDraw() в міру необхідності. Кожен раз, коли ваше зображення на полотні вимагає перемальовування, необхідно викликати метод invalidate(). Він вимагає від системи оновлення уявлення, і система тоді викличе ваш метод onDraw(). Оскільки ShapeDrawable має свій власний метод draw(), ви можете створити підклас View, який малює ShapeDrawable в коді методу зворотного виклику view.onDraw().


3.5.2 Bitmap

Будь-яке зображення, яке ми завантажуємо з графічного файлу, є набором кольорових крапок (пікселів). А інформацію про кожну точку можна зберегти в бітах. Звідси й назва – карта бітів або bitmap. Іноді використовується термін растр або растрове зображення. В Android є спеціальний клас android.graphics.Bitmap для роботи з подібними картинками.

При розміщенні в активності компоненту ImageView і присвоюванню атрибуту android:src ресурс з папок drawable-xxx, то система автоматично виводить зображення на екран.

Якщо потрібно програмно отримати доступ до бітової карти (зображенню) з ресурсу, використовується метод BitmapFactory.decodeResource().

Кожна точка зображення представлена у вигляді 4-байтного цілого числа. Спочатку йде байт прозорості – значення 0 відповідає повній прозорості, а 255 говорить про повної непрозорості. Проміжні значення дозволяють робити напівпрозорі зображення.

Наступні три байти відповідають за червоний, зелений і синій колір, які працюють за таким же принципом. Тобто значення 255 відповідає насиченому червоному кольору, тощо [21].

Так як будь-яке зображення – це набір точок, то за допомогою методу getPixels () ми можемо отримати масив цих точок і виконати над ними певні дії (поміняти прозорість або колір), а потім за допомогою спорідненого методу setPixels () записати нові дані назад в зображення. Так можна перефарбувати чорні пікселі в білі і навпаки. Якщо вам потрібна конкретна точка на зображенні, то використовуйте методи getPixel () / setPixel (). Подібний підхід використовується в багатьох графічних фільтрах. Врахуйте, що операція по заміні кожної точки у великому зображенні займає багато часу. Бажано проводити подібні операції в окремому потоці. Схема роботи головного та фонового потоку наведена в додатку Б.

Враховуючи обмежені можливості пам'яті у мобільних пристроїв, слід бути обережним при використанні об'єкта Bitmap щоб уникнути витоку пам'яті. Потрібно звільняти ресурси за допомогою методу recycle (), якщо вони більше не використовуються.

Якщо не замислюватися про ресурси пам'яті, то можна отримати помилку OutOfMemoryError. На кожен додаток виділяється обмежена кількість пам'яті (heap size), різна залежно від пристрою. Наприклад, 16мб, 24Мб і вище. Сучасні пристрої як правило мають 24Мб і вище, проте це не так багато, якщо ваш додаток зловживає графічними файлами.

Bitmap на кожен піксель витрачає в загальному випадку 2 або 4 байти (залежить від битности зображення – 16 біт RGB_555 або 32 біта ARGB_888). Можна порахувати, скільки витрачається ресурсів на Bitmap, що містить зображення, зняте на 5-мегапіксельну камеру.

При співвідношенні сторін 4:3 вийде зображення зі сторонами 2583 х 1936. У конфігурації RGB_555 об'єкт Bitmap займе 2592 * 1936 * 2 = близько 10Мб, а в ARGB_888 (режим за замовчуванням) в 2 рази більше – трохи більше 19Мб.

Щоб уникнути проблем з пам'яттю використовуються методи decodeXXX () класу BitmapFactory.

Якщо встановити атрибут largeHeap в маніфесті, то додатком буде виділено додатковий блок пам'яті.

Маніфе́ст (лат. manifestus - явний, очевидний) - Урочисте письмове звернення верховної влади до народу з приводу якоїсь дуже важливої події (прийняття важливого законопроекту, оголошення війни тощо). Писане звернення політичної партії або громадської організації, яке має програмний характер.

За допомогою методу createScaledBitmap () можна змінити розмір зображення. В останньому параметрі у методу йде булева змінна, що відповідає за згладжування пікселів. Зазвичай його застосовують, коли маленьке зображення збільшують в розмірах, щоб поліпшити якість картинки. При зменшенні, як правило, в цьому немає такої необхідності [22].

Існує кілька перевантажених версій методу Bitmap.createBitmap (), за допомогою яких можна скопіювати ділянку зображення. Щоб вивести частину картинки, можна спочатку створити потрібний растровий із заданими розмірами, занести в масив кожен піксель вихідного зображення, а потім цей же масив повернути назад.

У класу Bitmap є метод getConfig (), який повертає перерахування Bitmap.

Перерахування - це тексти, розбиті на пункти й підпункти, що мають цифрове чи буквенне позначення.

Config.

Всього існує кілька елементів перерахування:


  • Bitmap.Config ALPHA_8 – кожен піксель містить у собі інформацію тільки про прозорість, про колір тут нічого немає. Кожен піксель вимагає 8 біт (1 байт) пам'яті;

  • Bitmap.Config ARGB_4444 – застаріла конфігурація, починаючи з API 13. Аналог ARGB_8888, тільки кожному ARGB-компоненту відведено не по 8, а по 4 біта. Відповідно піксель важить 16 біт (2 байти). Рекомендується використовувати ARGB_8888;

  • Bitmap.Config ARGB_8888 – на кожен з 4-х ARGB-компонентів пікселя (альфа, червоний, зелений, блакитний) виділяється по 8 біт (1 байт). Кожен піксель займає 4 байта. Володіє найвищою якістю для картинки;

  • Bitmap.Config RGB_565 – червоному і та синього компоненту виділено по 5 біт (32 різних значень), а зеленому – шість біт (64 можливих значень). Картинка з такою конфігурацією може мати артефакти. Кожен піксель займатиме 16 біт або 2 байти. Конфігурація не зберігає інформацію про прозорість. Можна використовувати в тих випадках, коли малюнки не вимагають прозорості та високої якості.

Конфігурація RGB_565 була дуже популярна на старих пристроях. Зі збільшенням пам'яті і потужності процесорів дана конфігурація втрачає актуальність. Різниця між якістю зображення показана на рисунку 3.4 [23].
http://www.curious-creature.org/blog/wp-content/uploads/2010/12/bitmap16_comparison.png

Рисунок 3.4 – Різниця між якістю зображення різних конфігурацій.

3.5.3 SurfaceView

Клас SurfaceView надає об'єкт Surface, який підтримує малювання у фоновому потоці і дає можливість використовувати OpenGL для тривимірної графіки. Це відмінний варіант для насичених графікою елементів, які потребують частих оновленнях або повинні відображати складну графічну інформацію, як у випадку з іграми та тривимірною візуалізацією.

Візуалізація - унаочнення, створення умов для візуального спостереження.

SurfaceView – обгортка навколо класу SurfaceHolder, який у свою чергу служить обгорткою класу Surface, використовуваного для оновлення зображення з фонових потоків.

В основі SurfaceView об'єкт Surface, а не Canvas. Це важливо, тому як Surface підтримує малювання з фонових потоків. Дане відміну особливо корисно для ресурсномістких операцій або швидких оновлень, а також коли необхідно забезпечити високу частоту зміни кадрів (використання тривимірної графіки, створення ігор або передперегляд відеопотоку з камери в режимі реального часу.

Можливість малювати незалежно від графічного потоку веде до підвищеного споживання пам'яті. Таким чином, хоч це і корисний (а іноді просто необхідний) спосіб створення нестандартних уявлень, будьте обережні, використовуючи його.

SurfaceView використовується точно таким же чином, як будь-які похідні від View класи. Ви можете застосовувати анімацію і розміщувати їх всередині розмітки так само, як і інші уявлення.

Застосовуючи OpenGL, ви можете малювати на Surface будь підтримувані двовимірні або тривимірні об'єкти, отримуючи при цьому усі вигоди від апаратного прискорення (якщо таке є). Таким чином, ви значно підвищуєте продуктивність, якщо порівнювати з тими ж операціями, виконаними на двовимірному Canvas.

Об'єкти SurfaceView особливо підходять для відображення динамічних тривимірних зображень, наприклад, в інтерактивних іграх, їх можна назвати кращим вибором для відображення попереднього перегляду відеопотоків з камери в режимі реального часу.

Щоб створити даний тип, наслідуйте клас SurfaceView і реалізуйте інтерфейс SurfaceHolder.Callback, що описує функцію зворотного виклику. Він повідомляє уявлення про те, що вихідний об'єкт Surface був створений / знищений / модифікований і передає в об'єкт SurfaceHolder посилання, що містить допустимий екземпляр Surface.

Типовий шаблон проектування SurfaceView передбачає класи, похідні від Thread, які беруть посилання на поточний об'єкт SurfaceHolder і негайно його оновлюють [24].


1   ...   9   10   11   12   13   14   15   16   17



  • 3.5.1 Canvas
  • 3.5.2 Bitmap
  • 3.5.3 SurfaceView