Sem vložte zadání Vaší práce.
České vysoké učení technické v Praze Fakulta informačních technologií Katedra softwarového inženýrství
Bakalářská práce
Skládání fotografií pro platformu iPhone Dominik Veselý
Vedoucí práce: Ing. Martin Kačer, Ph.D.
14. května 2012
Poděkování Chtěl bych poděkovat Martinu Kačerovi za vedení této práce a také za rady a konstruktivní kritiku. Rodičům za podporu při studiu. Šárce za pomoc se stylistikou a korekturou. Anežce, Angelice, Kristýně a Tereze, bez nichž by aplikace nevznikla. A také všem ostatním, kteří svými připomínkami a poznámkami dopomohli ke vzniku aplikace.
Prohlášení Prohlašuji, že jsem předloženou práci vypracoval samostatně a že jsem uvedl veškeré použité informační zdroje v souladu s Metodickým pokynem o etické přípravě vysokoškolských závěrečných prací. Beru na vědomí, že se na moji práci vztahují práva a povinnosti vyplývající ze zákona č. 121/2000 Sb., autorského zákona, ve znění pozdějších předpisů, zejména skutečnost, že České vysoké učení technické v Praze má právo na uzavření licenční smlouvy o užití této práce jako školního díla podle § 60 odst. 1 autorského zákona.
V Praze dne 14. května 2012
..................... 7
České vysoké učení technické v Praze Fakulta informačních technologií c 2012 Dominik Veselý. Všechna práva vyhrazena.
Tato práce vznikla jako školní dílo na Českém vysokém učení technickém v Praze, Fakultě informačních technologií. Práce je chráněna právními předpisy a mezinárodními úmluvami o právu autorském a právech souvisejících s právem autorským. K jejímu užití, s výjimkou bezúplatných zákonných licencí, je nezbytný souhlas autora.
Odkaz na tuto práci Dominik Veselý. Skládání fotografií pro platformu iPhone : Bakalářská práce. Praha: ČVUT v Praze, Fakulta informačních technologií, 2012.
Abstract This thesis describe creation of native iPhone application, which allows user to create collage of pictures composed of smaller individual tiles so the final photo looks like the model photography. A user can always see what stand/position should the photographed person take to achieve the most accurate final result as possible and then the application adjusts and stacks each photo. Thesis contains analytic and realization part and also detailed description of the iPhone platform and its technology. Keywords iPhone, photography, collages, iOS
Abstrakt Práce se zabývá tvorbou nativní iPhone aplikace, která bude uživateli umožňovat nafotit fotografické koláže složené z jednotlivých dílků tak, že výsledná fotografie odpovídá vybrané předloze ze vzorníku. Uživatel vždy na displeji zařízení vidí, jakou pozici má zaujmout, aby výsledný obraz byl co nejvěrohodnější, a aplikace jednotlivé fotografie sama upraví a seskládá. Práce obsahuje návrh i realizaci aplikace a také detailní popis platformy a jejích technologií. Klíčová slova iPhone, fotografování, koláže, iOS
9
Obsah Odkaz na tuto práci . . . . . . . . . . . . . . . . . . . . . .
8
Motivace . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15 15
Úvod
1 Popis řešeného problému 1.1 Stanovení cílů . . . . 1.2 Funkce detailněji . . . 1.3 iOS . . . . . . . . . . . 1.4 Dostupné tvary . . . . 1.4.1 Srdce . . . . . . 1.4.2 Hvězda . . . . . 1.4.3 Živá Abeceda .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
2 Použité technologie 2.0.4 Všeobecné informace . . . . . . 2.0.5 Cocoa . . . . . . . . . . . . . . 2.0.6 Objective-C . . . . . . . . . . . 2.0.7 LLVM a Clang . . . . . . . . . 2.0.8 Vrstvy a jednotlivé frameworky 2.0.9 Knihovny třetích stran . . . . . 2.0.10 Vývojové prostředí . . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
17 17 17 19 19 19 20 21
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
23 23 24 25 29 32 35 38
3 Analýza a návrh 3.1 Analýza aplikace PhotoShape . . . . . . . . . . . 3.1.1 Business analýza . . . . . . . . . . . . . . 3.1.2 Business procesy . . . . . . . . . . . . . . 3.1.3 Funkční a nefunkční požadavky na aplikaci 3.1.3.1 Funkční požadavky aplikace . . . 3.1.3.2 Nefunkční požadavky aplikace . . 3.1.4 Doménový model . . . . . . . . . . . . . . 3.2 Návrh Aplikace . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
39 39 40 40 42 43 43 44 45
11
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
3.2.1
Podrobnější návrh fotografické části . . . . . . . . . .
4 Realizace 4.1 Implementace galerie . . . . . . . . . . 4.2 Implementace jednotlivých tvarů . . . 4.2.1 Průběh vytváření tvaru . . . . . 4.2.2 Zobrazení finálních náhledů . . 4.2.3 Skládání koláže . . . . . . . . . 4.3 Fotografování jednotlivých dílků . . . . 4.3.1 Zobrazení předlohového obrázku 4.3.2 Proces zachycování snímků . . . 4.3.3 Úprava snímku . . . . . . . . . 4.4 Úpravy v knihovnách a grafické prvky . 4.4.1 Načítání obrázků . . . . . . . . 4.4.2 Obrazovka s náhledy . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
46 49 49 51 52 52 54 55 56 57 57 59 59 59
5 Ověření funkcionalit 61 5.1 Testování uživatelského rozhraní . . . . . . . . . . . . . . . . 61 5.2 Testování funkcionalit . . . . . . . . . . . . . . . . . . . . . 62 5.3 Ověření požadavků . . . . . . . . . . . . . . . . . . . . . . . 62 Závěr 63 Možná rozšíření do budoucna . . . . . . . . . . . . . . . . . . . . 63 Spuštění aplikace . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 Literatura A Porovnání předloh A.1 Tvar srdce . . . A.2 Tvar hvězdy . . A.3 Živá abeceda .
65 a . . .
výsledných fotografií 67 . . . . . . . . . . . . . . . . . . . . . . . . 67 . . . . . . . . . . . . . . . . . . . . . . . . 67 . . . . . . . . . . . . . . . . . . . . . . . . 67
B Struktura Tříd
75
C Obsah přiloženého CD
79
12
Seznam obrázků 1.1 1.2 1.3
Náčrt tvaru srdce na jednotlivých dílcích . . . . . . . . . . . . . Náčrt tvaru hvězdy na jednotlivých dílcích . . . . . . . . . . . . Náčrt textu z živé abecedy na jednotlivých dílcích . . . . . . . .
20 21 22
2.1 2.2 2.3
Jak zapadá Cocoa do systému iOS . . . . . . . . . . . . . . . . Celý proces kompilování našeho zdrojového kódu . . . . . . . . Porovnání kompilátoru clang a gcc 4.0 . . . . . . . . . . . . . .
25 30 31
3.1 3.2 3.3 3.4
AS-IS Proces: Nafocení koláže . . . . TO-BE Proces: Nafocení koláže . . . Diagram pohybu obrazovek při focení Diagram pohybu obrazovek při focení
. . . .
41 42 44 47
4.1 4.2 4.3
Galerie nafocených obrázků . . . . . . . . . . . . . . . . . . . . Náhled finálního tvaru po dofocení všech fotografií . . . . . . . . Obrazovka s detailem jednoho dílku koláže, s možností přefocení daného obrázku, či přeunu na jiné obrázky z koláže . . . . . . . Náhled focení jednoho z dílků koláže . . . . . . . . . . . . . . . Zachycení obrázku . . . . . . . . . . . . . . . . . . . . . . . . .
50 53
Předloha tvaru srdce vytvořená v ateliéru . . . . . . . . . . . . Výsledný obrázek tvaru srdce vytvořený aplikací . . . . . . . . . Další ukázkový obrázek tvaru srdce . . . . . . . . . . . . . . . . Obrázek, na kterém vzhledem k venkovním podmínkám a oděvu nevynikne tvar uplně dokonale. . . . . . . . . . . . . . . . . . . A.5 Předloha tvaru hvězdy vytvořená v ateliéru . . . . . . . . . . . A.6 Výsledný obrázek tvaru hvězdy vytvořený aplikací . . . . . . . . A.7 Další ukázkový obrázek tvaru hvězdy . . . . . . . . . . . . . . . A.8 Předloha nápisu „piknik“ vytvořená v ateliéru . . . . . . . . . . A.9 Výsledný obrázek nápisu „piknik“ vytvořený aplikací . . . . . . A.10 Předloha nápisu „friends“ vytvořená v ateliéru . . . . . . . . .
68 69 70
4.4 4.5 A.1 A.2 A.3 A.4
13
. . . . . . . . tvaru tvaru
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
54 56 57
70 71 72 73 74 74 74
Seznam obrázků A.11 Výsledný obrázek nápisu „friends“ vytvořený aplikací, na kterém se projevil vliv okolního počasí a je vidět, jak se zvyšujícím se šerem, kvalita fotografii klesá . . . . . . . . . . . . . . . . . .
74
B.1 První polovina struktury tříd a souborů . . . . . . . . . . . . . B.2 Druhá polovina struktury tříd a souborů . . . . . . . . . . . . .
76 77
14
Úvod Motivace Nápad na aplikaci, která bude sloužit k tvorbě fotografických koláží, jsem dostal již před jedním rokem. Dostal jsem darem jednu takto vytvořenou fotografii a kdokoliv ji viděl, tak se nad ní pozastavil a komentoval, jak se mu líbí. Řekl jsem si, že by určitě bylo mnohem jednodušší pokud by existovala aplikace, která Vám pomůže podobné fotografie vyfotit nějakým jednoduchým a rychlým způsobem, ale zároveň aby výsledné fotografie byly co nejbližší požadovanému výsledku. A tak celý nápad vznikl a do doby, než jsem ho rozhodl začít realizovat v rámci bakalářské práce, se častokrát změnila podoba a vize aplikace. Jelikož se nějaký čas věnuji programování aplikací pro mobilní zařízení, byla volba, jaký typ zařízení pro výslednou aplikaci zvolit, celkem jednoduchá a zároveň vzhledem k povaze aplikace a jejím požadavkům (fotoaparát, přenositelnost) nejrozumnější, jelikož mobilní zařízení tyto požadavky splňuje v základu v sobě. Po důkladném průzkumu současných aplikací na mobilní platformy jsem usoudil, že žádná taková aplikace zatím neexistuje, a proto je můj nápad originální a má smysl ho realizovat. V současné době je na trhu mnoho aplikací na úpravu již vyfocených fotografií, aplikace na pořizování speciálních fotografií jako jsou panoramatické fotografie nebo fotografie se speciálním filtrem. Avšak žádná aplikace na trhu nenabízí to, o co bych se v rámci své práce chtěl pokusit. Záměrem je vytvořit aplikaci, která bude uživateli jednoduše umožňovat vytvoření speciálních fotografických koláží, kde osoba pomocí jiných poloh rukou a těla, bude vytvářet určité obrazce, které se spojí ve výslednou koláž a vytvoří tak jeden finální obrázek podle vybrané předlohy. 15
Úvod
Aplikace musí být co nejjednodušší a musí uživateli nabídnout rychlou a spolehlivou cestu, jak výsledného obrázku docílit. Vzhledem k povaze aplikace jsou cílovou skupinou především mladí lidé od 12 do 25 let, zejména dívky, které baví takovéto druhy fotografií fotit, například jako profilové fotografie na sociální síťě nebo jako dárek pro přítele. Samozřejmě aplikaci mohou využívat i lidé, kteří nespadají do výše uvedené skupiny.
Volba platformy V současné době existují pouze 3 velké platformy, pro které by mělo smysl aplikaci vytvářet: iOS od společnosti Apple, Windows Phone od Microsoftu a Android od Googlu. Já jsem si vybral platformu iOS od společnosti Apple, protože se vývojem na této platformě zabývám již delší dobu, a také protože je mezi cílovou skupinou oblíbený, jelikož neběží pouze na chytrých telefonech, které nejsou v této skupině tak zastoupené, ale také na přehrávači iPod Touch, který je mezi cílovou skupinou hodně populární.
16
Kapitola
Popis řešeného problému 1.1
Stanovení cílů
Tento nadpis nás přivádí k tématu cílů a očekávané úspěšnosti. Úspěch se samozřejmě nedá nikterak předpovídat, ale doufám, že s ohledem na originálnost, uživatelskou základnu a také fakt, že aplikace bude dostupná po celém světě zdarma, jako úspěch budu považovat dosažení alespoň 5000 unikátních stažení. Vzhledem k tomu, že aplikace bude zdarma, neočekávám žádně finanční úspěchy, osobně bych považoval za největší úspěch, kdyby se nápad prosadil a zařadil se mezi známé tituly této platformy, velkou radost by mi udělalo, kdyby například nějaký tématicky relevantní zpravodajský server provedl recenzi aplikace, či se o ní někde někdo zmíní. Nakonec ve výsledku by pro mě byl úspěch i to, že čas od času narazím na internetu na fotografickou koláž vytvořenou z mojí aplikace. Aby bylo vidět, že aplikaci opravdu někdo využívá a nevytvářel jsem ji tedy úplně nadarmo.
1.2
Funkce detailněji
Jak jsme se dozvěděli v předchozí kapitole, aplikace bude uživatele provádět krok za krokem celým procesem vytvoření fotokoláže. Od výběru typu koláže přes zobrazení fotografických tipů, focení jednotlivých dílků koláže, možností jednotlivé fotografie přefotit až po samotné složení finální fotografie a možnosti jejího sdílení do několika kanálů. Aplikace po startu zobrazí úvodní obrazovku s logem, která se bude zobrazovat do té doby, než se načtou všechny potřebné prostředky. Poté se zobrazí hlavní obrazovka aplikace, která bude disponovat čtyřmi okny.
17
1
1. Popis řešeného problému V prvním okně budeme moci vybrat a nafotit jednotlivé koláže, druhé okno bude fungovat jako galerie již nafocených koláží, kde si fotografie můžeme prohlížet a znovu sdílet. Ve třetím okně se budou nalézat tipy a návody na používání aplikace, aby uživatel mohl aplikaci používat co nejsnadněji a nejefektivněji, jak jen to jde. V poslední obrazovce nalezneme informace o aplikaci a autorovi. Pokud se vydáme volbou první obrazovky a tedy nafocení nové koláže, nejdříve musíme vybrat, jakou koláž budeme fotit. V první fázi budou k dispozici koláže „Srdce“, „Hvězda“ a „Živá abeceda“. Po zvolení typu koláže se nám zobrazí detaily o tomto typu, například kolik lidí je potřeba, jaké jsou vhodné podmínky na focení a jaké oblečení je vhodné. Poté už pouze stačí stisknout jedno tlačítko a aktivujeme fotografický režim, ve kterém nás aplikace opět provede krok za krokem. Jako první aplikace zkontroluje, zda se v aplikaci nachází nějaké nafocené fotky koláže tohoto typu, pokud ano, zeptá se nás, jestli chceme pokračovat v rozfoceném tvaru, pokud ne, začneme od začátku. Aplikace bude zobrazovat jednotlivé pózy na displeji společně s reálným přenosem obrazu z kamery. Musíme dostat fotografovanou osobu do takového postavení, aby se překrývala a přesně kopírovala „pózu“ na obrazovce. Poté zmáčkneme tlačítko pro sejmutí snímku a fotografie se zobrazí na displeji (již ořízlá podle vodících linek). Rozhodneme, zda je fotografie v pořádku či nikoliv. Pokud se nám fotka nebude líbit, budeme moci nafotit novou fotografii pro aktuální pózu, pokud jsme s fotografií spokojení, aplikace se přesune na další pózu. Takto se celý proces opakuje pro všechny fotografie potřebné k získání koláže. Po nafocení všech potřebných fotografií se nám zobrazí tabulka zmenšených fotografií, které budou znázorňovat koláž a mřížka se bude zobrazovat přesně tak, jak má vypadat finální koláž (každá koláž má jiný tvar). Zde si můžeme všechny fotografie naposledy prohlédnout a rozhodnout se, zda chtějí fotografii vyfotit znovu. Když budeme s výsledkem spokojeni, zmáčkneme tlačítko, které spustí finální skládání koláže. Po dokončení se aplikace přesune do galerie a zobrazí námi právě vytvořenou koláž, kde si ji poprvé můžeme prohlédnout ve finální podobě. Odtud ji můžeme sdílet do několika dostupných kanálů. Při focení tvarů jsou používané předlohy, podle kterých se uživatel řídí, tyto předlohy byly vytvořeny ve fotoateliéru. Protože některé tvary jsou symetrické, stačilo nám nafotit pouze polovinu těchto fotografií. Aplikace pozná o jakou variantu se jedná a podle toho předlohovou fotografii otočí, aby uživatel vždy věděl jak přesně se má postavit, aby výsledná koláž měla co nejvyšší kvalitu.
18
1.3. iOS
1.3
iOS
Proč jsem si platformu vybral, jsem vysvětlil v úvodu. Zde je krátký souhrn poažadavků aplikace na platformu. Aplikace potřebuje operační systém iOS nejméně ve verzi 4.0 nebo novější. V době psaní této práce je nejnovější verze systému 5.1 a ještě letos se očekává vydání verze 6.0 a zařízení musí být vybaveno fotografickou čočkou a čipem. Toto jsou jediná hardwarová a softwarová omezení této aplikace.
1.4
Dostupné tvary
V době vymýšlení celého konceptu aplikace jsem celou dobu počítal se třemi tvary pro uvedení aplikace. Od začátku jsem počítal s koláží ve tvaru srdce z důvodu, které jsem uvedl v úvodu. Když jsem přemýšlel, co by měly být další tvary, zamyslel jsem se, co by mohlo mít u cílové skupiny úspěch a napadlo mě využít skládání textů z živé abecedy. Uživatel si vybere text a pomocí aplikace ho nafotí a aplikace složí výslednou fotografii. Jako poslední tvar jsem zvolil hvězdu, která se bude vytvářet podobně jako srdce, ale za pomoci jiných předlohových fotografií.
1.4.1
Srdce
Koláž srdce se bude skládat z 24 fotografií, 6 sloupců a 4 řádků, na kterých se bude nacházet 14 tvarových fotografií a 10 fotografií vyplňovacích. Jelikož srdce je symetrické, stačí nám nafotit pouze polovinu potřebných fotografií a aplikace se postará o zbytek a fotografie se sama zrcadlově otočí podle potřeby. Na nafocení tohoto tvaru nám proto bude stačit 8 fotografií. Samozřejmě pokud uživatel bude chtít, může ve výsledku fotografií vyfotit více, místo již zrcadlově otočených fotografií, může také znovu vyfotit některé výplňové fotografie.
19
1. Popis řešeného problému
Obrázek 1.1: Náčrt tvaru srdce na jednotlivých dílcích
1.4.2
Hvězda
Hvězda je vytvořena podobně jako srdce, skládá se ze stejného počtu fotografií a stejně tak jako srdce, jedná se o symetrický tvar, takže nám stačí nafotit pouze polovinu tvarových fotografií a alespoň 3 výplňové fotografie. Opět se uživatel může rozhodnout, zda chce některé fotografie vyměnit. Rozdíl je v počtu fotografií, které tvoří tvar, pro hvězdu to je 16 tvarových fotografií a ostatní opět tvoří výplň. Rozdíl je samozřejmě také ve výsledném tvaru a v předlohách. 20
1.4. Dostupné tvary
Obrázek 1.2: Náčrt tvaru hvězdy na jednotlivých dílcích
1.4.3
Živá Abeceda
Živá abeceda se od předchozích tvarů liší nejvíce, jelikož nemá pevný tvar a na většinu písmen jsou na rozdíl od předchozích tvarů potřeba dva lidé. Při spuštění tvorby tohoto tvaru si uživatel bude moci vybrat, jaký text chce nafotit, a to až na 3 řádky s omezením 12 znaků na řádek. Po té začneme fotografovat od začátku textu po jednotlivých písmenech. Jestliže jsou na focení potřeba 2 lidé, stejně tak i předlohy se skládají z fotografií na kterých dvě dívky tvoří jednotlivá písmena abecedy. Nejsou zde povolené žádné speciální znaky, ani písmena s háčky a čárky. Jediný povolený znak, kromě 26 písmen, je mezera oddělující slova, kde uživatel vyfotí pouze fotografii 21
1. Popis řešeného problému pozadí. Abeceda sice nemůže být symetrická, a tak by se zdálo, že musíme nafotit všechny fotografie v koláži, ale i na toto aplikace myslí a nemusí tomu vždycky tak být. Pokud text, který chceme nafotit obsahuje 2 a více stejných písmen, tak pozná, že už toto písmeno má vyfoceno a použije ho. Stejně jako u předchozích tvarů se při finálním prohlížení nafocených fotografií můžete rozhodnout, že některou fotografii chcete vyfotit znovu a nahradit předchozí použitou.
Obrázek 1.3: Náčrt textu z živé abecedy na jednotlivých dílcích
22
Kapitola
Použité technologie Platforma iOS vznikla v roce 2008 s první verzí telefonu iPhone. Zanedlouho společnost Apple vydala verzi svého hudebního přehrávače iPod ve verzi touch, což byl vlastně iPhone, který nedisponoval GPS a GSM modulem, nicméně byl také vybavený systémem iOS. V roce 2010 Apple vydal tablet iPad, ve kterém také začal používat systém iOS, který se do té doby jmenoval iPhone OS, ale jelikož ho v tuto chvíli používali již 3 různá zařízení, tak se název systému unifikoval. Systém v současné verzi 5.1 běží na těchto zařízeních: • iPhone 3G, iPhone 3GS, iPhone 4, iPhone 4S • iPod Touch 3rd Generation, iPod Touch 4th Generation • iPad, iPad 2, iPad 3
2.0.4
Všeobecné informace
iOS je operační systém na bázi UNIXu běžící na jádře Mach, které Apple používá i ve svém desktopovém operačním systému Mac OS X a jehož kořeny sahají až do BSD. Podporuje architekturu ARMv6 a ARMv7, na které jsou postavené všechny procesorové čipy, které jsou srdcem všech výše uvedených zařízení. Systém využívá pro zabezpečení unixový jail a každá aplikace dostane vyhrazený „sandbox“ a mimo něj nemůže zapisovat ani číst. Komunita samozřejmě přišla na to, jak jail prolomit a nainstalovat tak do zařízení dodatečné služby a aplikace, které by se jinak do telefonu kvůli některým přísným restriktivním opatřením nedostaly. Například aplikace, které přistupují k některým zakázaným částem systému přes takzvané 23
2
2. Použité technologie „Private-API“, které je určeno pouze pro vývojáře Apple. V dřívějších dobách, kdy byl systém mladý a postrádal spoustu důležitých funkcí, byla móda „Jailbreaku“ velice populární, během pár let vývojáři systému ty nejzásadnější funkce, kvůli kterým lidé tuto metodu podstupovali, postupně naimplementovali a tak je tento trend poslední dobou na ústupu, jelikož již nepřináší takovou značnou výhodu.
2.0.5
Cocoa
Cocoa je sada objektově orientovaných frameworků, které přináší jak runtime prostředí pro aplikace běžící na systémech Mac OS X a iOS, tak i sadu objektově orientovaných knihoven, které nabízí všechny stavební bloky, které jsou potřeba k naprogramování iOS aplikace. Runtimová část se stará o zobrazování uživatelského rozhraní a volání nižších systémových procedur. Cocoa aplikace se primárně píší v jazyce Objective-C, který si popíšeme později. Existují samozřejmě i alternativní cesty, jak vytvořit aplikace postavené a běhu schopné na frameworcích Cocoa, ať již využití tzv. mostů pro jiné jazyky nebo přímo kompilace do nativního kódu ARM procesorů, ale o tom si také povíme v později. Cocoa pro platformu iOS se nazývá Cocoa Touch. Dva nejdůležitější frameworky, které nám postačí k tvorbě aplikací pro iOS, Foundation a UIKit. První jmenovaný obsahuje všechny základy, jak název samotný napovídá, datové typy, chování objektů, objektové obaly na primitivní datové typy a systémová volání. UIKit nadruhou stranu řeší zobrazování grafických prvků, jejich definice a správu událostí. Cocoa samozřejmě obsahuje spoustu jiných již nepovinných frameworků, které opět přináší povětšinou objektově orientované rozhraní pro práci s jinými komponentami, jako jsou například mapy, práce s adresářem nebo dokonce grafické operace, které jsou akcelerované přímo přes grafický čip. Spektrum nabízených frameworků je velice široké. Podrobnější popis těchto knihoven, které byly potřeba pro tvorbu mojí práce, si popíšeme v dalších sekcích. Rád bych ještě upřesnil drobnou nejasnost, která mohla vzniknout v této sekci. O Cocoa se říká, že je to sada objektově orientovaných knihoven, ale jelikož jsou napsány v jazyce Objective-C, které je nadstavbou ANSI C, není nezbytně nutné, že všechny knihovny musí mít objektově orientované rozhraní. Většina knihoven ho má, ale pár výjimek se přeci najde, kde musíme volání provádět procedurálně a také musíme s pamětí zacházet trochu opatrněji, což přináší mnohá úskalí. Naštěstí těchto neobjektově orientovaných částí v Cocoa moc není. 24
Cocoa framework je postavený na architektuře MVC (Model View Controller) a díky objektovosti a dynamičnosti jazyka Objective-C využívá vnitřně několik návrhových vzoru (Observer, KVO a Adapter) a objektových paradigmat (Messaging a Dynamické typování).
Obrázek 2.1: Jak zapadá Cocoa do systému iOS
2.0.6
Objective-C
V předchozí sekci jsme několikrát zmínili jazyk Objective-C, který se primárně využívá k programování iOS a Mac OS X aplikací. Celé aplikační rozhraní těchto systémů a knihovny jsou napsané v tomto jazyce. Jedná se o objektově orientovaný, reflektivní jazyk, který vychází z principů jazyka SmallTalk, který byl jedním z prvních objektových programovacích jazyků. Samotný jazyk Obj-C je nadstavbou nad jazykem ANSI C a má velice neobvyklou syntaxi při volání metod (posílání zpráv) a je potřeba si na ni zvyknout, hlavně když ji mícháme s onou klasickou „Céčkovou“. Jak jsem již zmínil v předchozím odstavci, v jazyce Obj-C se nevolají metody, ale stejně jako ve SmallTalku se posílají zprávy a celkově ke své dynamičnosti a objektovosti má mnoho zajímavých vlastností, které bych chtěl zmínit. Posílání zpráv Je základní koncept „volání metod“ převzatý z jazyka SmallTalk. Objektu se za běhu programu pošle zpráva a objekt, pokud na zprávu umí odpovědět, tak odpoví spuštěním příslušného bloku v paměti. V jazycích jako je například Java, kde má každá metoda vyhrazené místo v paměti a po jejím zavolání se tento blok paměti spustí. V objective-C je zpráva definována tzv. 25
2. Použité technologie selektorem, což je vlastně řetězec definující název zprávy. Když v runtimu objekt dostane zprávu označenou identifikátorem „zprava“, runtime se přistoupí do tabulky, kde jsou uložené všechny selektory, které k sobě mají spárované pointery do paměti, kde se nachází implementace dané metody. Díky tomu, že selektor je pouze řetězec, jsme schopni velice dynamicky rozhodovat o tom, jaká zpráva se pošle i za běhu programu. Například podle odpovědi ze vzdáleného serveru.
Dynamické typování Stejně jako SmallTalk i Obj-C podporuje dynamické typování, což mimo jiné znamená, že objekt může dostat zprávu, kterou nemá nadefinovanou ve svém rozhraní. Tato vlastnost nám umožňuje přeposílání zpráv dál jiným subjektům a díky tomu můžeme velice jednoduše naimplementovat například návrhový vzor Observer. Dynamické typování nám zároveň umožňuje ukládání různých objektů do jedné kolekce, avšak musíme si dávat pozor na jejich přetypování na správný objekt, když je z kolekce vyndaváme.
Kategorie Kategorie jsou podle mého názoru jedna z nejlepších vlastností tohoto jazyka. Díky jeho dynamičnosti nám dovolují rozšířit existující třídu nebo upravit stávájící chování, aniž bychom museli využít dědičnost. Toto je velice silná vlastnost, představme si, že máme třídu, která se používá v celém systému a používá jí i několik doprovodných knihoven třetí strany (například třídu reprezentující obrázek). Framework, který nám vrací standardní obrázek, upravit nemůžeme, ale zároveň víme, že potřebujeme třídu rozšířit o některé funkce, které potřebujeme volat. Jednoduše vytvoříme kategorii pro tuto třídu a požadovanou metodu naimplementujeme. Avšak je potřeba si uvědomit, že použití kategorií k přepsání chování již existující metody může být velice nebezpečné, hlavně pokud upravujeme základní systémové třídy a neznáme jejich původní chování.
Protokoly Protokoly jsou určitou obdobou rozhraní definující, jaké metody objekt, který protokolu podléhá, implementuje. Avšak opět díky dynamickému typování může obsahovat i nepovinné metody, které objekt implementovat nemusí, ale opět si musíme dávat pozor na to, kdy tyto metody voláme. 26
Deklarované vlastnosti Objective-C nám umožňuje nadefinovat atributy pro třídu, kterým pak kompilátor sám vygeneruje kód. Toto se velice hodí převážně na iOS, kde nemáme k dispozici Garbage Collector a paměť spravujeme ručně. Nadefinujeme, že atribut „Jméno“ je typu NSString, zda-li má být pouze ke čtení a jak chceme, aby vygenerované metody pracovaly s pamětí a kompilátor se nám postará o to, že v runtimu budou tyto metody k dispozici na zavolání.
Bloky Bloky jsou realizací anonymních funkcí (v jiných jazycích také jako closures, či lambda výrazy). Odkazují na ně „block pointers“, většinou se používají jako jednorázové callbacky po vykonání nějakého úkolu. Další využití nalezneme při multitaskingu přes technologii Grand Central Dispatch, (technologie vyvinuta společností Apple pro efektivní spouštění paralelních operací na více jádrových procesorech) kde jednotlivé kusy kódu, které chceme pustit paralelně, obalíme do bloku. Tuto druhou možnost jsem využil v aplikaci opravdu hodně, například při zpracování fotografíí na pozadí tak, aby se uživateli nezaseklo grafické rozhraní.
Všechny výše uvedené výhody tohoto jazyka jsem využíval při tvorbě své práce a v části, kde popisuji realizaci, se vždy zmíním, v čem mi daná výhoda jazyka pomohla k dosažení toho, co jsem potřeboval. I přes všechny výhody, které jsem popsal výše a mnoho dalšího, má i jazyk Obj-c svá úskalí, která opět zkusím vypsat stručně v jednotlivých bodech.
Hlavičkové soubory Vzhledem k faktu, že jazyk Objective-C je nadstavbou nad ANSI C, vyžaduje rozhraní zapsané v hlavičkových souborech, což mi přijde v dnešní době moderních jazyků jako je Java / C#, a vzhledem k tomu, že se Objective-C snaží být stejně moderní a neustále se vyvíjí, trošku nešťastné. Nejen, že se nám zvýší počet souborů na dvojnásobek, ale musíme řešit ruční importování hlavičkových souborů a správně definovat jejich rozhraní. 27
2. Použité technologie Absence jmenných prostorů Tato nevýhoda jde ruku v ruce s hlavičkovými soubory a ztěžuje nám práci. V Javě jednoduše rozdělíme třídy do balíčků a v C#/C++ do jmenných prostorů, což v Objective-C nejde a to znamená, že musíme všechny třídy pojmenovávat unikátně. V praxi se doporučuje dávat každé naší třídě unikátní prefix, což nám přidělává starosti s psaním názvů tříd při deklaracích a importech. Syntaxe Syntaxe je opravdu nezvyklá a i když je celkem jednoduché si na ni navyknout, opět to přináší další nepříjemnosti pro programátora. V syntaxi volání zpráv, kde každá zpráva je v hranatých záložkách a zprávy se mohou řetězit do sebe, se člověk opravdu jednoduše ztratí a není moc přehledná. Navíc můžeme v podstatě libovolně míchat C a Obective-C syntaxi na přehlednosti kódu častokrát nepřidá. Poslední třešničkou na nepřehledném dortu jsou direktivy Objective-C, které začínají znakem @ a deklarují začátek a konec třídy, implementace, či ono zmiňované deklarování atributů, či například try/catch klauzuli. Správa paměti Ačkoliv se v nejnovější verzi jazyka Objective-C nalézá garbage collector, stejně jako ve všech moderních jazycích bohužel není dostupný na platformě iOS. Musíme tedy využít počítání referencí, takže jsme nuceni ručně zvedat a snižovat počet referencí a objekty uvolňovat ručně, přičemž lze samozřejmě udělat spoustu lehce přehlédnutelných chyb, které se navíc špatně odlaďují. Máme možnost použití Autorelease poolů, které se starají o to, aby objekty, které alokujeme a zavoláme na ně „Samouvolnění“ (které znamená, že objekt není uvolněn ihned, ale v brzké době při dalším běhu runloopu) se opravdu uvolnily, například v každém cyklu. Autorealease pooly se používají například pokud v cyklu vytvaříme velké množství objektů a potřebujeme je opravdu včas uvolnit. Naštěstí při použití kompilátoru Clang máme možnost využít automatického počítání referencí, což nám práci výrazně usnadňuje, ale o tom podrobněji hned v příští sekci.
I když trpí některými nedostatky, je jazyk opravdu vyspělý a nabízí mnoho vylepšení díky své dynamičnosti a objektovosti a po technické stránce je výborný se všemi dostupnými frameworky a dostupnými technologiemi. 28
Na druhou stranu postrádá přívětivost pro programátora. Všechny neduhy, které jsem popsal programátorovi výrazně ztěžují práci.
2.0.7
LLVM a Clang
Když už máme kód napsaný, potřebujeme, aby nám ho něco převedlo do spustitelné podoby na našem zařízení. Laik by si asi řekl, že necháme tuto práci našemu vývojovému prostředí a nebude se o celý proces zajímat, ale pro nás je to celkem důležitá součást, a proto bych tuto problematiku rozebral. Pro celý proces používal Apple dříve překladač GCC, který se postaral o celou režii od Preprocesingu až po slinkování. Později Apple zvolil variantu kompilátorové infrastruktury LLVM s GCC frontendem, což přinášelo mnohem lepší výsledky oproti první variantě. A nakonec relativně nedávno Apple přišel s tím, že GCC uplně vyřadí a bude nadále používat infrastrukturu LLVM s frontendem Clang. Mohlo by se zdát, že pokud nám nejde o čas, je volba kompilátoru pouze drobnost, ale není tomu tak. Low Level Virtual Machine Jak jsem již napsal výše Low Level Virtual Machine, dále jen LLVM, je kompilátorová infrastruktura navržená pro„Compile-Time“,„Link Time“ a „Run Time“, která vznikla v roce 2000 jako rešeršní projekt na Univerzite Illinois. I přes svůj název má s virtuálními stroji společného málo, respektive je to pouze jedna z věcí, která se pomocí LLVM dá postavit. Infrastruktura se dělí na front-end a back-end. Front-end má na starosti vzít vstupní kód a vygenerovat z něj bytecode, kterému rozumí back-end LLVM. Vzhledem k dostupnému API k LLVM jsme schopni napsat frontend téměř z libovolného jazyka (Tohoto například využívá firma Adobe pro svůj jazyk ActionScript, či projekt Monotouch (1).). Backend LLVM pak převezme bytekód a zkompiluje ho do nativního strojového kódu výstupní platformy. Tento přístup nám umožňuje neomezovat se pouze na jazyk ObjectiveC a pokud najdeme front-end pro náš programovací jazyk, můžeme psát nativní aplikace pro iOS i v jiném jazyce. Další podrobnosti o tom, jak funguje LLVM pro nás nejsou zas tak důležité, pro nás je důležitý především front-end Clang. Clang Clang je front-end kompilátor v infrastruktuře LLVM, který si poradí s „Céčkovskými“ jazyky jako C,C++,Objective-C. Kompilátor stejně jako celou infrastrukturu LLVM sponzoruje firma Apple a stejně tak se podílí na jeho vývoji. 29
2. Použité technologie
Objective-C kód
Linker
Front End (CLang)
Back End (LLVM)
Hotová aplikace
Obrázek 2.2: Celý proces kompilování našeho zdrojového kódu
Clang má oproti konkurenčnímu GCC mnohem rychlejší kompilační čas a také menší spotřebu paměti. GCC má zase naopak výhodu, že jeho výstup může být do několika různých architektur, Clang podporuje pouze výstup do LLVM byte-kódu. Těch výhod má Clang oproti GCC více, ale my se zaměříme pouze na ty, které jsou pro nás důležité. Clang má výborné nástroje na statickou analýzu kódu, která je integrována do vývojového prostředí a díky níž odhalíme mnoho chyb a nedostatků, aniž bychom museli program složitě debuggovat, ale samozřejmě odhalí jen určitě chyby. Pro nás je ale nejpodstatnější novinka, která přišla relativně nedávno. 30
Obrázek 2.3: Porovnání kompilátoru clang a gcc 4.0
Jak jsem se zmiňoval, na platformě iOS není dostupný garbage collector a o správu paměti se tedy musíme starat sami. Objective-C řeší alokaci a dealokaci objektů pomocí počítání referencí, což může být někdy dost pracné, protože si musíte pamatovat přesně, která funkce počet referencí zvyšuje a která nikoliv. Počítání referencí není náchylné jen na občas těžko objevitelné chyby, protože předčasné uvolňování objektu není nejjednodušší na krokování, ale také musíme psát hodně kódu, který nejen, že zabere čas, ale také kód částečně znepřehlední. Od nové verze LLVM 3.0 můžeme ve front-endu Clang využít ARC (Automatic Reference Counting). Automatické počítání referencí je skvělá věc. Kompilátor sám při kompilaci odvodí, kdy byl objekt vytvořený, kdy se má počet referencí zvýšit a kdy naopak snížit a vše při kompilaci doplní jako bychom to tam psali sami, ale s tím rozdílem, že kompilátor chybu neu31
2. Použité technologie dělá. Takže nám to odbourá všechno to nepříjemné psaní kolem. Což nám ušetří skoro celou práci s pamětí, proč skoro celou? Například knihovny třetích stran, které nelinkujeme již zkompilované, bychom museli kompletně upravit, pokud používáme ARC, tak nemůžeme paměť spravovat ručně, ale i na to existuje způsob, kde můžeme každému souboru nastavit compiler flag, který udává, že soubor nechce používat ARC a že v něm paměť budeme spravovat my. A nakonec, i když se nestaráme o zvyšování/snižování počítadla referencí, musíme objektům nastavit, jak se s nimi má zacházet, zda-li se jedná o silnou či slabou referenci (abychom předešli cyklickým referencím) a nebo, že se jedná o primitivní typ a tudíž se žádné reference nepočítají. Pravděpodobně největší výhodou je tato flexibilita, kdy je na nás, zda ARC použijeme či ne a především, že použití nás nic „nestojí“. Protože všechny operace Clang provádí při kompilaci, program se pak tedy chová stejně, jako kdybychom paměť spravovali sami a tak nás nečeká žádné zpomalení, zvýšená paměťová zátěž a nebo zvýšená režie jako při použití Garbage Collectoru. Z principu je tedy ARC mnohem účinnější než používání Garbage Collectoru výměnou za pár řádek, kde musíme nastavit, o jaký typ reference se jedná. A ve výsledku je pouze na nás, zda-li budeme automatické počítání referencí používat a nebo ne. Já jsem se rozhodl ho ve své práci používat, protože jsem s jeho použitím měl dobré zkušenosti. Pouze jsem musel u knihoven třetích stran nastavit, aby se na ně ARC neuplatňoval.
2.0.8
Vrstvy a jednotlivé frameworky
Systém iOS se skládá ze čtyř vrstev, které drží celý systém pohromadě. Každá vrstva dává programátorovi jinou sadu možností, jak vhodně implementovat části aplikace podle potřeb, které se pro ten daný účel hodí nejvíce. Obecně platí, že by programátor měl upřednostňovat frameworky z vyšších vrstev před těmi z nižších a pokud zjistí, že nesplňují jeho požadavky, tak by měl hledat nástroje a funkce v nižších vrstvách, pro které nástroje z vyšších vrstev tvoří jen objektově orientovanou abstrakci, což většinou znamená mnohem jednodušší přístup a také mnohonásobně sníží množství kódu, který je potřeba k napsání dané úlohy. Ovšem pokud frameworky z vyšších vrstev nenabízí dostatečné rozhraní pro náš cíl, musíme sáhnout do nižších vrstev. Během psaní Bakalářské práce jsem musel využít nástroje 32
ze všech 4 vrstev. Postupně si je rozebereme a vždy popíši, k čemu jsem danou vrstvu upotřebil. Cocoa Touch Cocoa Touch je nejvyšší vrstva a obsahuje nejvíce „high level“ funkcí a knihoven. Definuje základní infrastrukturu aplikace a také věcí jako například multitasking, tisk a více-dotyková gesta prsty. Právě na této vrstvě bychom měli hledat funkce z frameworků pro naši aplikaci a pokud nepochodíme, je vhodné nahlédnout níže. Z této vrstvy toho v aplikaci používám opravdu mnoho: všechny grafické prvky, gesta prsty. Některé z dostupných frameworků v této vrstvě. • UiKit - framework pro práci se zařízením a veškerými grafickými prvky • MapKit - umožňuje nám pracovat s mapou, vyhledávat, umísťovat špendlíky... • Message - dovoluje nám psát emaily a sms zprávy přímo z aplikací Media Ve vrstvě média se nalézají knihovny pro veškerou práci s grafikou, obrazem, zvukem a k nim svázaným technologiím. Obsahuje mocný framework Core Graphics známý také jako Quartz, který zvládá nativní 2D vektorové a bitmapové renderování a animace. Obsahuje také OpenGL ES knihovnu na renderování 2D a 3D pomocí hardwarové akcelerace. Nechybí ani knihovna na práci se zvukem, která nám dovolí nahrávat, spouštět či upravovat zvuk jakkoliv chceme. A nakonec pro nás nejzajímavější framework AVFoundation, díky kterému celá aplikace může fungovat. AVFoundation obsahuje nástroje pro práci s obrazem zachyceným skrze fotoaparát a umožňuje nám pořizovat snímky a dále s nimi pracovat. Výše zmíněný framework CoreGraphics se podílel stejně intenzivně na finálním díle, veškeré práce s obrázky jako je zmenšování, zrcadlení a skládání výsledných koláží, běží právě přes tento framework, a proto je pro nás neméně podstatný. S jistotou můžeme tvrdit, že tento framework je pro povahu naší aplikace ten nejvyužívanější. A proč jsme nepoužili na výše uvedené věci něco z vyšší vrstvy, jak je doporučeno? Protože jsme potřebovali opravdu specifické operace, na které vrstva Cocoa Touch nezná řešení. Na závěr představím ještě pár ostatních knihoven z této vrstvy, které jsem nepoužil. 33
2. Použité technologie • CoreImage - tato knihovna nabízí velkou škálu Hardwarově akcelerovaných funkcí pro práci s obrázky, bohužel je dostupná pouze na nejnovějším systému a to by nám zabránilo podporovat i dřívější verzi operačního systému. • MediePlayer - tento framework nám nabízí pohodlnou práci s přehráváním a ovládáním videa. Core Services Tato vrstva obsahuje fundamentální systémové služby, které používají všechny aplikace, i když je nepoužíváme přímo, několik částí systému je na nich postaveno, jedná se poslední mezikrok mezi samotným systémem a vyšší vrstvou. Tato vrstva například spravuje službu Grand Central dispatch, která nám poskytuje jednoduché rozhraní na vykonávání asynchronních požadavků. Nalézá se zde také organizování dat ve službě iCloud, kterou společnost Apple nedávno představila a všechny výměny a synchronizace probíhají na této vrstvě. Systém iOS má v sobě zabudovaný i databázový server SQLite, který můžeme použít k tvorbě databází tak, jak je známe, ukládat do nich data aplikace a dále s nimi pracovat. Z výše uvedených knihoven používám přímo pouze Grand Central Dispatch, na zpracovávání obrázků na pozadí, zatímco grafické prostředí se stále aktualizuje. Kdybychom chtěli v aplikaci zprovoznit i funkce na sdílení, používali bychom i knihovnu pro práci se službou iCloud. Výše jsme popisovali celý Cocoa Framework, tak právě druhý z těch dvou nejdůležitějších, Foundation framework, se nachází právě v této vrstvě. Některé další zajímavé frameworky na této vrstvě: • CoreData - Je objektová abstrakce nad SQLite, která nám dovoluje pracovat s daty jako objekty, jedná se tedy o ORM framework (jako například Hybernate v javě) • MediaPlayer - Tento framework nám nabízí pohodlnou práci s přehráváním a ovládáním videa se základními ovládacími prvky. Core OS Toto je nejspodnější vrstva celého systému iOS. Vývojář jí většinou nepoužívá přímo, ale všechny frameworky z vrstev výše ji v sobě využívají. Jedná 34
se opravdu o velice nízkoúrovňovou sadu frameworků pro práci s hardwarem či nejnižšími systémovými operacemi. Pokud například chceme pracovat s technologií Bluetooth, tak framework pro zpřístupnění této funkcionality nalezneme právě zde. Stejně tak, pokud chceme vytvářet externí příslušenství, které se připojuje přes třiceti pinový konektor, který má každé iOS zařízení. Ovšem pro oficiální tvorbu těchto příslušenství musíme projít speciální certifikací od společnosti Apple. Dalším zajímavým frameworkem v této vrstvě je Security, který obsahuje nástroje pro správu certifikátů, identit a soukromých i veřejných klíčů. Navíc obsahuje i implementace některých šifer jako například HMAC. V neposlední řadě obsahuje i celosystémovou klíčenku pro různá hesla, která chcete mít dostupná z různých aplikací. Na této vrstvě se tedy vyskytují i nejzákladnější systémová volání. Nejlepší bude když si některé z nich vypíšeme v bodech. • Vlákna (POSIX) • Alokace paměti • Přístup do souborového systému a základní I/O operace • Síťování (BSD sokety) • Bonjour a DNS služby • Matematické operace
2.0.9
Knihovny třetích stran
Stejně jako pro jiné platformy i pro iOS existuje celá řada knihoven a frameworků, které slouží k zjednodušení určitých činností či vytvoření obsáhlejších aplikačních struktur. Některé knihovny slouží třeba jako nadstandardní grafické elementy, některé obalují již hotové procedury z Cocoa touch frameworku, které se stále zdají složité. Další jsou balíčky užitečných funkcí, které se mohou programátorovi hodit a které jazyk či základní systémové funkce nenabízejí. Poslední skupinou jsou celé aplikační frameworky, které v sobě obsahují všechny výše zmíněné typy knihoven (jako například SpringFramework v Javě nebo ZendFramework v PHP). Hlavní aplikační framework Hlavních aplikačních frameworků pro Cocoa Touch moc není (Cocoa Touch je sám o sobě aplikační framework). Existuje pár nadstaveb, mezi nimiž 35
2. Použité technologie jednoznačně vybočuje jedna a tou je framework Three20, kterou vyvinula společnost Facebook pro svojí vlastní aplikaci a poté uvolnila její zdrojový kód. Nyní se o framework stará převážně komunita, která ho dál rozšiřuje. Bohužel uživatelská základna není moc veliká, ale přesto rozhodně patří mezi nejpopulárnější komunitní projekty na platformě iOS. Dokumentace v podstatě neexistuje, a proto je učící křivka tohoto frameworku opravdu pomalá a většina věcí se musí dohledat přímo ve zdrojovém kódu, což je sice velice nepraktické, ale na druhou stranu opravdu pochopíte, jak která komponenta funguje. Zatím se nezdá, že by používání tohoto frameworku bylo jednoduché a opravdu není. Používám ho již déle než rok a musel jsem strávit opravdu hodně hodin naučením se základních principů i detailů. Naštěstí existuje dost návodů dělaných komunitou a mailová skupina či diskuzní fórum projektu jsou často dobrým pomocníkem, kde jsem našel nejednu odpověď. Komunita je velice aktivní také na pravděpodobně nejznámějším programátorském serveru stackoverflow.com, kde k současnému dni existuje přes 900 otázek označených značkou vztahující se k tomuto frameworku. Proč jsem si tedy nakonec framework, jehož nevýhody jsem zmínil výše, zvolil? Protože jsem s ním po té době již velice sžitý a protože oproti jiným nabízí spoustu funkcionalit a jedná se v podstatě o jediný aplikační komplexní framework, který zaštituje v podstatě každou oblast vývoje aplikací pro iOS. Vypíši v bodech některé z klíčových vlastností této knihovny: • Správa obrazovek aplikace a jejich přechodů pomocí URL schémat. • Funkce pro správu s řetězci a základními grafickými elementy • Stylování aplikace podobně jako když webové stránky používají CSS • Práce s tabulkami a datovými modely načítanými z internetu či jiných zdrojů • Jednodušší práce s HTTP požadavky • Obrázky načítané z internetu včetně automatického cachování • Mnoho vlastních grafických komponent jako například okno pro tvorbu zpráv a příspěvků • Práce s galeriemi obrázku včetně detailů a náhledů 36
V aplikaci z frameworku používám hlavně velice sofistikovanou galerii, kterou jsem ale musel hodně upravit pro potřeby mojí aplikace, například v základu je pevně daná velikost obrázků a jejich počet na řádek v obrazovce s náhledy, bohužel tyto hodnoty nejdou nikterak jednoduše nastavit a upravovat samotný framework by nebyl správný přístup, využil jsem dědičnosti a kategoríí (o těch jsem psal výše), abych dosáhl požadovaného výsledku. Nadále používám stylování, které umožňuje používat jednu specifickou barvu či styl písma na více místech stejně jako v CSS. Využívám i jiných grafických prvků, jako například speciální tlačítka, která se ve frameworku nalézají. Používám i obecné funkce, které se hodí na běžnou programátorskou práci v daném jazyce, povětšinou funkce, které zkracují některé zdlouhavé konstrukce atp.. Práce s obrázky V aplikaci na několika místech využívám i knihovnu na všeobecné operace s obrázky, jako například zprůhlednění, zmenšení, ořez nebo kulacení rohů. Tuto sadu funkcí napsal programátor Trevor Harmon a používám ji ve většině svých projektů a za tu dobu jsem si do ní některé funkce i dopsal.(12) Knihovna na sdílení Protože výsledné obrázky bude uživatel určitě chtít sdílet a v dnešní době má na výběr z mnoha možných kanálů od MMS zprávy přes elektronickou poštu až po všechny možné sociální síťě, které jsou v dnešní době velkým hitem. Protože většina těchto sítí má vlastní API pro nahrávání dat jako jsou fotografie a jejich implementace by nám zabrala spoustu času a napsání takovýchto API pro několik sítí by samo obsáhlo téma nějaké bakalářské práce, komunita naštěstí tento problém řeší knihovnou ShareKit, která umožňuje sdílet různé druhy medií přes sociální sítě nebo jiné kanály. Problém, který tato knihovna má, je ten, že nových sociálních sítí moc není, a proto je její kód poněkud zastaralý a tudíž například nepodporuje funkci automatického počítání referencí a musíme všechny její zdrojové kódy označit tak, aby kompilátor tuto skutečnost bral v potaz. Některé z kanálů, které aplikace podporuje pro sdílení zhotovených koláží: • Email 37
2. Použité technologie • Facebook • Tumblr • Twitter • Flickr
2.0.10
Vývojové prostředí
Společnost Apple dodává vývojářům zdarma celé SDK, které obsahuje několik klíčových komponent pro tvorbu aplikací. SDK obsahuje vývojové prostředí XCode, nástroj pro navrhování a skládání grafických elementů aplikace, kompilátor, simulátor, pokud nechceme nebo nemůžeme dělat vývoj na reálném zařízení (má však dost omezené hardwarové funkce) a také dokumentaci s jednotlivými buildy operačního systému. Vývojové prostředí XCode prošlo během let vývoje mnoha zásadními změnami, ta největší nastala v roce 2010, kdy Apple vydal XCode s pořadovým číslem 4, ve kterém se změnilo celé grafické rozhraní. A přibylo mnoho nových funkcí. Prostředí umí přes klávesovou zkratku zobrazovat „protičást“ k danému souboru hlavičkový soubor k implementačnímu a naopak. Další výhoda je používání záložek, jak je známe z webových prohlížečů, záložky si můžeme nastavovat a dávat jim jména, což nám usnadní práci, pokud nějaký proces automatizujeme a chceme při něm mezi jednotlivými záložkami přepínat. XCode je hodně náročný na zdroje a zabírá celkem hodně operační paměti a celé SDK také není nejmenší, na pevném disku zabere něco kolem 4GB. Editoru chybí některé pokročilé textové úpravy, na které jsem zvyklý ze svého oblíbeného IDE Eclipse, ale jinak je celé SDK jednoduché na používání a mnoho věcí potřebných pro vývoj ulehčuje.
38
Kapitola
Analýza a návrh Než se pustíme do samotného programování, je potřeba celý problém rozebrat na několik částí. Nejdříve musíme program analyzovat, zjistit jeho podstatné části a určit funkční i nefunkční požadavky. Poté je potřeba navrhnout vhodné technologie a datové struktury a zároveň vymodelovat jednotlivé komponenty aplikace. Součástí návrhu je mimo jiné i navržení celého objektového modelu, pokud možno nezávisle na platformě. Což je bohužel v našem případě trošku složitější, protože vytváříme aplikaci pro specifickou platformu, což je definované v nefunkčních požadavcích. Návrh je ale přesto natolik obecný, že půjde adaptovat na jiné systémy s většími či menšími změnami. V této kapitole se tedy budeme zabývat všemi aspekty analýzy a návrhu aplikace tak, jak jsem postupoval při její tvorbě.
3.1
Analýza aplikace PhotoShape
Mezi součásti analýzy softwarového projektu patří Bussines analýza, která popisuje proč a za jakým účelem se aplikace dělá, co by měla uživateli nabízet a jaký přínos bude mít na současnou scénu. Dále je potřeba provézt analýzu bussines procesů, to jsou procesy, které by měly poukázat na již existující procesy využívání stávajícího systému (pakliže tvoříme novější verzi již stávájícího systému), kterým se říká procesy „AS-IS“ a ty samé procesy bychom měli ukázat řešené v našem novém systému, těmto procesům se říká „TO-BE“. A výsledně dvojice procesů spolu porovnat. Procesy „TO-BE“ by měly přinést nějaké vylepšení, ať už přidání možností či funkcí, tak i zjednodušení celého procesu, což usnadní 39
3
3. Analýza a návrh práci uživateli. Pokud vytváříme nový systém, můžeme jako proces „ASIS“ využít stávájící činnosti, které lidé museli vykonat aby dosáhli stejného výsledku za účelem splnění stejného cíle. Další částí analýzy je nadefinování funkčních i nefunkčních požadavků pro aplikaci. Funkčními požadavky se rozumí veškerá funkcionalita, kterou musí aplikace disponovat. Nefunkčními požadavky se rozumí vše, co musí aplikace splňovat, ale nesouvisí to s funkcemi (například podporované platformy, technologie, zařízení). Poslední částí Analýzy je Doménový model, který nám umožní separovat a určit hlavní entity aplikace a vytvořit jednotlivé vazby mezi nimi.
3.1.1
Business analýza
Cílem je vytvořit aplikaci pro zařízení vybavené fotografickým čipem a fungující na platformě iOS, která bude umožňovat nafotit fotografické koláže podle předem daných předloh a která fotografie samá upraví a seskládá do výsledných koláží. Aplikace bude nabízet jednoduchého a přívětivého průvodce, který umožní uživateli jednoduše nafotit jednotlivé části koláže tak, že bude zobrazovat předlohu formou vodotisku přes displej fotoaparátu a uživatel ihned uvidí, že focená osoba splňuje předlohu a může ji vyfotit s vědomím, že výsledná koláž bude vypadat podle představ. Aplikace by měla umožňovat i okamžité přefocení jednotlivých fotografií, pokud s nimi uživatel není spokojen. Aplikace musí fotografie upravit a seskládat zcela sama, aby měl uživatel co nejjednodušší práci a celý proces trval co možná nejkratší dobu. Aplikace bude umožňovat všechny zhotovené fotografie ve fotogalerii, ve které si uživatel bude moci koláže prohlédnout a případně je nasdílet přes některé dostupné kanály.
3.1.2
Business procesy
V aplikaci se vzhledem k její přímočarosti mnoho procesů nevyskytuje. Aplikace má v podstatě jediný hlavní účel, a to nafotit koláž s co největší jednoduchostí a pohodlností. Ostatní podpůrné procesy jsou tedy nepodstatné.
40
3.1. Analýza aplikace PhotoShape Hlavní proces, který znázorňuje postup tvorby koláží, jsem znázornil na následujících diagramech aktivit. Chci nafotit specifickou koláž
Musím najít předlohu - Internet - Tvorba vlastní předlohy - Knihy
Nafotím Potřebné fotografie
Uložím je do počítače
Jsou fotografie podle předlohy
Ne
Ano Upráva Fotografií - Oříznu fotografie - Seskládám do výsledného obrázku
Výsledná fotografie
Obrázek 3.1: AS-IS Proces: Nafocení koláže Jak je z diagramů zřejmé, stávající proces je komplikovaný, zdlouhavý a především není vůbec jednoduchý a výsledek není zaručen. Nafotit přesně určité tvary a pózy tak, aby na sebe navazovaly a aby výsledné fotografie šly seskládat do výsledné koláže, je velice pracné a často vyžaduje složitý ořez, což pak zase nedává jednotlivým dílkům jednotný vzhled. Upravování fotografií na PC je pro většinu uživatelů velkou překážkou a zároveň dlouho 41
3. Analýza a návrh Chci nafotit specifickou koláž
Zvolím koláž dostupnou v aplikaci
Nafotím potřebné fotografie s předlohou v aplikaci
Aplikace vygeneruje výsledný obrázek - Aplikace sama ořízne fotografie - Aplikace sama složí finální koláž
Výsledná fotografie
Obrázek 3.2: TO-BE Proces: Nafocení koláže
trvajícím procesem. Naopak nový proces všechny tyto neduhy a nepříjemnosti eliminuje. Protože jestli fotografie nezapadá do výsledné koláže zjistíme hned a ne až po stažení fotografií do PC. Zároveň aplikace sama ořeže fotografie podle rámečku předlohy, takže udělá práci za nás a všechny fotografie budou mít jednotný vzhled, protože ořez bude stále na stejném místě původní fotografie. Aplikace za nás již upravené dílky složí a uloží do naší kolážové fotogalerie.
3.1.3
Funkční a nefunkční požadavky na aplikaci
Co jsou funkční i nefunkční požadavky jsme si vysvětlili výše. Ze zadání a předchozích bodů analýzy jsme schopni tyto požadavky pro aplikaci vypsat. 42
3.1. Analýza aplikace PhotoShape 3.1.3.1
Funkční požadavky aplikace
• Musí obsahovat vzorník dostupných koláží • Musí sama upravovat nafocené fotografie • Musí sama skládat jednotlivé dílky do výsledné koláže • Uživatel musí mít možnost jednotlivé fotografie vyfotit a vyměnit • Pro symetrické či stejné dílky aplikace vytvoří kopii nebo zrcadlový obraz • Musí obsahovat fotogalerii již nafocených koláží • Koláže se budou moci dále sdílet alespoň skrze tyto služby – Email – Facebook – Flickr • Bude obsahovat ovládací tlačítka pro zapnutí/vypnutí blesku pro zařízení, která jsou jím vybavena • Nebude obsahovat možnost ovládání digitálního přiblížení • Bude obsahovat stránku s tipy a triky pro používání aplikace 3.1.3.2
Nefunkční požadavky aplikace
• Musí fungovat na zařízeních se systémem iOS 4.3 a vyšší a zároveň obsahujících fotografický čip • Bude distribuovatelná skrze Apple App Store • Výsledný distribuční balíček by se měl vejít pod hranici 50MB, kvůli stahování bez Wi-Fi připojení. • Cílová skupina - hlavní cílová skupina jsou mladí lidé 12 - 25 let 43
3. Analýza a návrh
3.1.4
Doménový model
Při analyzování aplikace jsem došel k závěru, že obsahuje tyto hlavní entity. „Tvar“, „Dílek koláže (Photo)“, „Výslednou fotografii (GalleryPhoto)“ a „Zmenšeninu dílku pro náhled tvaru ThumbPhoto“. Výsledná fotografie je entitou, která se dá dále upravovat či poslat dál a zobrazuje se ve fotogalerii. Mnohem podstatnější jsou pro nás entity zabývající se tvarem. Nejdůležitější entitou je tvar, který v sobě skrývá veškeré informace o výsledné koláži, jako například:
Obrázek 3.3: Diagram pohybu obrazovek při focení tvaru
• fullSize - velikost výsledné koláže • photos - informace o každém dílku, počet dílků, z kterých se koláž skládá a průchod skrze jednotlivé dílky • name - jméno tvaru • Metody pro ukládání jednotlivých fotografií a výsledné skládání 44
3.2. Návrh Aplikace • Pomocné metody pro prací s tvarem a jeho jednotlivými částmi Jak si můžeme všimnout, tato entita v sobě obsahuje i informaci o jednotlivých dílcích tvaru/koláže. Tyto informace v sobě nese kolekce, která ukládá další entitu „Dílek“, který poskytuje tyto informace: • isMandatory - informace o tom, zda se jedná o povinnou tvarovou fotografii nebo pouze výplňovou • isMirror - informace o tom, zda se jedná o zrcadlovou kopii jiného dílku • x,y - souřadnice ve výsledné koláži • id,mirrorId - ID podle kterého se načte obrázková předloha pro tento dílek Ostatní entity, které hrají v aplikaci svou roli, jako například: „Galerie“, „Fotoaparát“, „Účty k sociálním sítím“ nejsou na diagramu znázorněny, jelikož jsou implementovány přímo v systému nebo je vytvářejí knihovny třetích stran. A přestože tyto třídy dál rozšiřuji a upravuji, rozhodl jsem se do diagramu znázornit pouze entity vytvořené mnou a které mají souvislost tvorbou tvaru.
3.2
Návrh Aplikace
Vzhledem k architektuře systému a použitých knihoven Cocoa Touch, jsem zvolil strukturu Model-View-Controller (MVC), která patří mezi strukturální návrhové vzory, kde data, logika a zobrazovací vrstva jsou odděleny a komunikace probíhá vždy přes vrstvu logickou (Controller). Pro aplikaci samotnou jsem zvolil styl zobrazovaní s pomocí spodního ovládacího panelu se záložkami, které jsem rozdělil na 4 základní tlačítka. • Tvary - hlavní obrazovka, přes kterou budeme provádět focení tvarů • Galerie - galerie již vytvořených obrázků • Tipy - obrazovka s tipy pro focení pomocí aplikace Photoshape • O aplikaci - obrazovka se základními údaji o aplikaci a autorovi 45
3. Analýza a návrh Nejdůležitější částí aplikace je první obrazovka s tvary a následnými obrazovkami a logikou pro pořízení tvaru. Galerie nepotřebuje žádný složitý návrh, bude pouze zobrazovat fotografie a jejich detailní náhledy. Další dvě stránky jsou víceméně statické a zobrazující data případně budou obsahovat odkazy vedoucí mimo aplikaci.
3.2.1
Podrobnější návrh fotografické části
Poté co si uživatel vybere tvar, který by chtěl nafotit, zobrazí se mu obrazovka informující ho o detailech o tomto tvaru, jak bude výsledná fotografie vypadat, kolik bude potřeba lidí k nafocení fotografie. Pokud se uživatel rozhodne nafotit tento tvar, objeví se obrazovka se zapnutým fotografickým režimem obsahující vodotiskovou vrstvu s obrázkem znázorňujícím předlohu pro tuto jednotlivou fotografii. Po vyfocení fotografie se nám zobrazí její náhled a my se můžeme rozhodnout, zda se nám fotografie líbí či nikoliv a případně ji můžeme nafotit znovu. Pokud se nám líbí, budeme pokračovat v celém procesu, až nafotíme všechny fotografie potřebné pro tvar. Po nafocení všech potřebných fotografií se nám zobrazí obrazovka se zmenšenými obrázky poskládanými do výsledného tvaru, kde si má uživatel poslední možnost prohlédnout a případně znovu vyfotit jednotlivé kousky koláže. Pokud je se všemi fotografiemi spokojen, může vytvořit výslednou fotografii a aplikace nám zobrazí finální koláž ve fotogalerii, kde ji můžeme dále sdílet.
46
3.2. Návrh Aplikace
Zvolím si tvar k nafocení
Zobrazím informace o tvaru Jak vypadá výsledný obrázek Kolik je potřeba nafotit fotografií Kolik potřebujeme lidí k nafocení
Zobrazíme fotoaparát
Zobrazíme další předlohu v sekvenci k nafocení
Zobrazíme obrazovku s vyfotografovaným obrázkem
Nafotíme obrazek znovu
ANO Jsme s obrázkem spokojeni?
NE
ANO
Jsou v sekvenci ještě další fotografie?
NE Nafotíme obrazek znovu
Zobrazím všechny dílky koláže Zde si je mohu prohlédnout Můžu je přefotit Můžu vytvořit výslednout koláž
Chci přefotit fotografii
47 Obrázek 3.4: Diagram pohybu obrazovek při focení tvaru
Kapitola
Realizace V této kapitole se budu zabývat realizací a problémy, které mě potkaly při implementaci mojí práce. Problémy s realizací byly povětšinou mírného charakteru, a vyřešil jsem je povětšinou nahlédnutím do dokumentace či krátkou konzultací. Během implementace jsem narazil i na spoustu problémů v kódu, které byly složitější na odhalení a špatně se odhalovaly i při krokování přes debugger, protože jsem si například nastavil break-point na špatné místo v kódu.
4.1
Implementace galerie
Jak jsem popisoval v úvodní kapitole, když potřebujeme na iOS ukládat data perzistentně, máme několik možností. Využít přímo zabudovaný databázový stroj SQLite, případně nadstavbu v podobě objektového mapování CoreData, ukládání přes Coder, a nebo přímo do speciálních XML souborů. Já jsem při tvorbě galerie usoudil, že databáze by byla v tomto případě zbytečně přehnané řešení, které by pro nás bylo i neefektivní. Já jsem zvolil cestu někde mezi. Použil jsem archivování objektu do speciálního XML. Vzhledem k tomu, že nepotřebujeme vyhledávání, ale pouze chronologické řazení, je pro naše potřeby ideální. Galerii jsem naprogramoval jako singleton (GalleryDb), který se inicializuje při startu aplikace a načte všechny informace o databázi. Poté co načtu informace o fotografiích, vytvořím pro každou z nich samostatný objekt (GalleryPhoto), který je uložen v synchronizované kolekci uvnitř singletonu databáze a obsahuje tyto informace. 49
4
4. Realizace • dateCreated - datum vytvoření obrázku • shapeName - druh koláže • thumbUrl, photoURL - cesta k detailu i náhledu • photoWidth, photoHeight - velikost detailní fotografie Při vytvoření nebo smazání fotografie se celá databáze automaticky pře uloží do nového souboru a to vše proběhne atomicky, abychom nemohli soubor porušit. Galerie obsahuje i metodu, která nám dokáže vrátit celé pole obrázků s informacemi potřebnými pro zobrazení celé obrazovky fotografií, takže třída slouží zároveň jako data-provider.
Obrázek 4.1: Galerie nafocených obrázků
Pro sdílení jednotlivých tvarů jsem použil knihovnu Share-Kit, která je ovšem trošku zastaralejší, a proto jsem musel všechny její soubory označit, aby nepoužívaly automatické počítání referencí, a proto byla implementace 50
4.2. Implementace jednotlivých tvarů této metody poněkud složitější. V knihovně jsem nastavil, přes které služby chci obrázek sdílet. Například pro Facebook jsem musel vytvořit přímo na stránkách facebooku svou aplikaci a obdržet tak svůj API klíč, přes který se bude moje aplikace hlásit a sdílet fotografie.
4.2
Implementace jednotlivých tvarů
Všechny tvary(HeartShape, StarShape, AlphabetShape) dědí od abstraktní třídy Shape, která definuje základní chování a vlastnosti všech tvarů a ostatní tvary pokud potřebují je upraví. Základním stavebním pilířem této třídy jsou atributy, které pro každý tvar nabývají jiných hodnot. • name,fullName - název tvaru • numOfPhotos - počet tvarových a doplňkových fotografií • numOfPeople - počet lidí potřebných k nafocení tvaru • passingArray - pořadí v jakém budou fotografie foceny a jejich rozmístění Toto jsou některé z důležitých vlastností každého tvaru. Dále má třída tvar svou sadu metod, které nám pomáhají s prací s adresáři a obsahuje všechny metody, které můžeme potřebovat při práci s tvarem. Nebo také metody, které nám umožňují vytvořit a zmenšit obrázky tak, jak potřebujeme pro další práci a nakonec nám umožní celý obrázek poskládat a uložit finální koláž na disk a do galerie. Některé z užitečných metod: • getShapeDirectory - zkontroluje, zda adresář pro tvar existuje a pokud ne, tak ho vytvoří • isShapeDirectoryEmpty - kontrola prázdnosti adresáře tvaru • deleteShapeDirectory - smazání obsahu adresáře • photoOrMirrorExists - kontrola, zda fotografie pro daný obrázek existuje, či jestli existuje její zrcadlová kopie • getPhotoforPhoto - vrácení fotografie pro konkrétní dílek nebo opět její zrcadlové kopie • getImageforPhoto - vrácení obrázku předlohy pro danou fotografii 51
4. Realizace Toto jsou některé z funkcí, které nám usnadňují práci s tvary a operacemi nad nimi. Pro práci s adresářovou strukturou a soubory jsem použil funkce z Foundation frameworku a pro všechny funkce, které operují s obrázky a grafickými kontexty používám CoreGraphics framework.
4.2.1
Průběh vytváření tvaru
Abstraktní třída definuje několik metod, které jsou potřebné pro celý průběh aplikace a volají se každá v určitých fázích. Některé z metod jsou implementovány v abstraktní třídě a některé si každý tvar musí implementovat sám. • init - zde by mely probíhat inicializace tvaru v případě Abecedy je to například zadání textu, který chceme nafotit • beforeCapture - Pokud tvar potřebuje nějaké donastavení před zapnutím fotoaparátu • runCapturing - Tato metoda se zavolá před spuštěním fotoaparátu • saveImage - uloží jednu fotografii a její náhled • process - zde se vezmou všechny nafocené fotografie a složí se z nich výsledná koláž a uloží • afterProcess - V této metodě můžeme nastavit cokoliv považujeme za nutné po složení koláže (například vymazat adresář s fotkami) Tyto metody nemusí být implementovány podtřídami, pokud nechtějí v těchto místech upravit standardní chování, protože základní implementace by měla postačit na tvorbu tvaru.
4.2.2
Zobrazení finálních náhledů
Když vyfotíme poslední fotografii, máme možnost si celou koláž prohlédnout tak, že vypadá složená, ale na jednotlivé dílky se dá klikat, aby se nám zobrazily v detailu a mohli jsme je případně vyfotit znovu. Na této obrazovce také poprvé vidíme zrcadlené fotografie, které pokud nechceme použít, můžeme také vyfotit znovu (například pokud chceme mít na fotografii jiný výraz). Toto je velice užitečné, protože uživatel má již velice detailní představu o finální podobě jeho koláže a zároveň může ještě využít posledních změn. 52
4.2. Implementace jednotlivých tvarů Protože se fotografie zobrazují v jiném pořadí, než v jakém jsou foceny a zároveň nemůžeme použít souřadnice z velkého obrázku, musel jsem vymyslet jiný způsob, jak docílit tohoto vzhledu ve finální koláži.
Obrázek 4.2: Náhled finálního tvaru po dofocení všech fotografií Fotografii jsem přiřadil ještě jeden atribut navíc, který celým číslem určuje pořadí v tomto okně s náhledy. Před tím než fotografie vyrenderuji, seřadím pole fotografií pomocí tohoto atributu. Díky dynamičnosti jazyka, kdy mohu na pole použít libovolný comparator a to ještě několika způsoby, rozhodl jsem se použít řazení pole, předat porovnávací funkci jako blok, protože toto řazení provádím pouze na jednom místě, bylo použití anonymní funkce jednoduchou, rychlou a zároveň efektivní volbou.
53
4. Realizace
Obrázek 4.3: Obrazovka s detailem jednoho dílku koláže, s možností přefocení daného obrázku, či přeunu na jiné obrázky z koláže
4.2.3
Skládání koláže
Skládání finálních koláží je asi nejdůležitější část aplikace, proto ji popíšu trochu podrobněji. Ve chvíli kdy uživatel stiskne tlačítko pro vytvoření koláže, tak se spustí algoritmus, který vytvoří grafický kontext o velikosti finálního obrázku, a poté projede všechny fotografie, které se mají v koláži objevovat a pro každou fotografii se přes funkci ve třídě tvar vrátí požadovaný obrázek, který je poté vložen na místo, které má vyznačeno. To, že každý jednotlivý obrázek je vložen na své místo nám zajišťuje, že kontext zamkneme přes klipovací masku a tím zajistíme, že se obrázek vykreslí pouze na pozici a rozměrech oné masky. Když máme všechny obrázky vloženy, nastává poslední fáze, kdy je obrázek z kontextu vyjmut a zmenšen jako náhled a následně uložen do databáze v obou velikostech. Metoda se vykonává asynchronně, aby nám „nezamrzlo“ uživatelské prostředí. Na konci této metody zašleme delegátovi zprávu a in54
4.3. Fotografování jednotlivých dílků formujeme ho o tom, že koláž byla vytvořena a ten nás přenese na detail koláže v galerii. Listing 4.1: Skládání koláže // Vytvorime g r a f i c k y k o n t e x t UIGraphicsBeginImageContext ( s e l f . f i n a l S i z e ) ; CGContextRef c u r r e n t C o n t e x t = UIGraphicsGetCurrentContext ( ) ; f o r ( i n t i = 0 ; i < s e l f . numOfPhotos ; i ++) { // Ulozime s o u c a s n y s t a v CGContextSaveGState ( c u r r e n t C o n t e x t ) ; UIImage ∗ image ; Photo ∗ photo = [ p a s s i n g o b j e c t A t I n d e x : i ] ; image = [ s e l f g e t P h o t o f o r P h o t o : photo ] ; // Vytvorime k l i p o v a c i masku , p r i l e p i m e j i na k o n t e x t a v y k r e s l i m e o b r a z e k do k o n t e x t u CGRect c l i p p e d R e c t = CGRectMake ( photo . x , photo . y , t i l e S i z e . width , t i l e S i z e . h e i g h t ) ; CGContextClipToRect ( c u r r e n t C o n t e x t , c l i p p e d R e c t ) ; [ image drawInRect : CGRectMake ( photo . x , photo . y , t i l e S i z e . width , t i l e S i z e . height ) ] ; CGContextRestoreGState ( c u r r e n t C o n t e x t ) ; } //Z k o n t e x t u vytahneme v y s l e d n y o b r a z e k UIImage ∗ c o l l a g e = UIGraphicsGetImageFromCurrentImageContext ( ) ;
4.3
Fotografování jednotlivých dílků
Pro fotografování jednotlivých dílků jsem využil většinu částí frameworku AVFoundation, který obsahuje vše potřebné pro práci s fotografickým čipem. Základním pilířem je třída CaptureManager, kterou jsem vytvořil a která zpřístupňuje přijímání dat z čočky a umožňuje s nimi dále pracovat. Jelikož programujeme aplikaci, která svým způsobem reprezentuje fotoaparát, data z čočky jsem se rozhodl dále posílat kanálem přes grafické rozhraní do animované vrstvy. Což nám umožní klasický živý náhled toho, co právě snímáme kamerou. Třída dále umožňuje pracovat s bleskem, čehož využívám k ručnímu přepínání blesku do režimů zapnuto a vypnuto. A co je pro nás asi nejdůležitější, můžeme snadno ovládat kameru a kdykoliv si vyžádat aktuální statický obrázek, při čemž můžeme využít mnoho různých nastavení jako u jiných digitálních fotoaparátů, včetně nastavení EXIF informací. 55
4. Realizace
4.3.1
Zobrazení předlohového obrázku
Každá fotografie má svůj předlohový vzor, který se nachází pro každý tvar ve stejném označeném obdélníku, jehož velikost a pozici si však každý tvar určuje sám. Předlohové fotografie mám nafocené od fotografa z atelieru a doma jsem je za pomocí editoru obrázků zmenšil a přizpůsobil potřebám aplikace, aby výsledný efekt byl co nejlepší. Obrázek se zobrazuje jako vrstva nad „živým náhledem fotoaparátu“ s 50% průhledností, takže uživatel vidí dobře jak předlohu, tak fotografovanou osobu. Kolem předlohového obrázku je barevnou čarou vyznačen obdélník, který znázorňuje snímanou část displeje, aby uživatel věděl, že co bude mimo tento obdélník, nebude na výsledné fotografii vidět.
Obrázek 4.4: Náhled focení jednoho z dílků koláže
56
4.3. Fotografování jednotlivých dílků
4.3.2
Proces zachycování snímků
Při zachycování snímku máme kromě možností jak fotografii vyfotit nastavit i „callback“ funkci, která se vykoná po skončení zachycení snímku. V našem případě opět použijeme anonymní funkci pomocí bloků, ve které data, tak jak nám z kamery přijdou, uložíme a přes notifikační centrum (které funguje jako návrhový vzor Observer) informujeme objekty, které si zažádaly informovat o tomto stavu, že obrázek se uložil. Po odeslání notifikace se v hlavním fotografickém controlleru spustí požadovaná metoda, která zajistí, že otevřeme modální obrazovku, na které zobrazíme aktuálně vyfotografovaný obrázek s možností znovu nafocení obrázku či pokračování v sekvenci. Zároveň se ale opět pomocí bloků a Grand Central Dispatch spustí v jiném vlákně metoda, která obrázek musí upravit a provést drobné korekce. Po skončení této metody se opět přes notifikační centrum modální okno dozví, že obrázek je již připraven a můžeme ho zobrazit a zároveň schovat panel, který nám oznamuje, že v současnosti aplikace provádí nějakou operaci, na jejíž dokončení se čeká. Návod
První spuštění
Text abecedy Init Smaže predchozí fotografie tvaru Pro každou fotku zjistí jestli již existuje Vyfotí fotografii Projede pole fotografii
Runloop
Nafocení tvaru
Zobrazí obrázek a nabídne nové focení Další spuštění Uloží zrcadlovou kopii pokud je to nutné Zobrazím tvar v podobě malých náhledů Logika, která je jiná pro každý tvar
BeforeProcess Process
Uložím do galerie Afterprocess Zobrazím finální fotografii a nabídnu odeslání
Obrázek 4.5: Zachycení obrázku
4.3.3
Úprava snímku
Poté co je obrázek vyfocen a my dostaneme jeho data, je potřeba obrázek oříznout a zmenšit. Protože chceme vyfotografovat pouze čtverec kolem 57
4. Realizace předlohové fotografie a čočka samozřejmě snímá mnohem větší plochu a nejde ji nikterak říci, aby vyfotografovala pouze určitou část displeje, musíme obrázek podle předlohy oříznout. Jelikož známe velikost displeje, velikost předlohového obrázku a jeho umístění relativně vůči displeji a také známe velikost fotografie, jsme schopni jednoduše obrázek oříznout tak, že výsledná fotografie bude obsahovat pouze to, co jsme viděli ve vyznačeném obdélníku na displeji. Vypočítáme si relativní poměr umístění obdélníku a jeho velikost vůči celkové fotografii a dostaneme rozměry našeho obdélníku uvnitř fotografie a podle tohoto vypočteného obdélníku fotografii ořízneme. Poté co máme fotografii oříznutou do našeho obdélníku, musíme ještě obrázek zmenšit na velikost jednoho dílku koláže. Tuto informaci má každý tvar uloženou v sobě stejně jako informace o předlohové fotografii, a proto informaci získáme a obrázek jednoduše zmenšíme.
Listing 4.2: Vyříznutí a zmernšení obrázku −(UIImage ∗ ) boundedImageWithImage : ( UIImage ∗ ) image andBounds : ( CGRect ) bound { // P r e p o c t u v y s k u a s i r k u pro v y r e z na v e l k e f o t c e CGFloat coefH = image . s i z e . h e i g h t / bound . s i z e . h e i g h t ; CGFloat coefW = image . s i z e . width / bound . s i z e . width ; CGFloat width , h e i g h t ; // P r e p o c t u v e l i k o s t i s posunem a p r e v e d u na pomer 2 : 3 h e i g h t = ( s e l f . photoRect . s i z e . h e i g h t +5)∗ coefH ; width = ( h e i g h t / 3 ) ∗ 2 ; //Frame k t e r y c h c i v y r i z n o u t s v e t s i v y s k o u a s i r k o u a j e o d s a z e n y do p r o s t o r u f o t k y // P r o h o z e n i s o u r a d n i c a v y s e k k v u l i opacnemu systemu s o u r a d n i c mezi UIKit a CoreGraphics CGRect frame = CGRectMake ( ( s e l f . photoRect . o r i g i n . y ) ∗ coefH , ( ( s e l f . photoRect . o r i g i n . x∗coefW ) ∗ 1 . 3 6 ) , h e i g h t , width ) ; CGImageRef imageRef = CGImageCreateWithImageInRect ( image . CGImage , frame ) ; UIImage ∗ cropped = [ UIImage imageWithCGImage : imageRef s c a l e : 1 . 0 o r i e n t a t i o n : image . i m a g e O r i e n t a t i o n ] ; CGImageRelease ( imageRef ) ; cropped = [ cropped r e s i z e d I m a g e : t i l e S i z e i n t e r p o l a t i o n Q u a l i t y : kCGInterpolationHigh ] ; return cropped ; }
58
4.4. Úpravy v knihovnách a grafické prvky
4.4
Úpravy v knihovnách a grafické prvky
Velkou práci dalo i upravit již existující komponenty, které využívám, aby se chovaly tak, jak je třeba pro potřeby naší aplikace. Povětšinou se jednalo o úpravy ve frameworku Three20, který je v aplikaci hojně používán. Převážně se veškeré úpravy týkaly v metodách pro práci s obrázky nebo v grafických prvcích zobrazující obrázky.
4.4.1
Načítání obrázků
Knihovna Three20 má vlastní třídu pro práci s obrázky, která je využívaná ve všech frameworkových komponentách a v základním nastavení podporuje pouze otevření dat z URL. Proto jsem musel pomocí kategorií upravit metodu, která se starala o parsování této URL a pomocí vlastního URL schématu jsem docílil toho, že obrázky se načítají z disku a dokonce si mohu říct o velkou či náhledovou verzi a nebo o klasický či zrcadlený obrázek. Po zadání příslušné URL obrázek,zobrazí přesně tu fotografii, kterou potřebujeme v potřebné velikosti a perspektivě.
4.4.2
Obrazovka s náhledy
Obrazovka s náhledy, která zobrazuje již zhotovené fotografie sestavené do výsledné koláže v základním režimu podporuje formát kde jsou 4 obrázky na řádek a obrázky mají pevnou velikost, což je pro nás ale nepřípustné, protože například pro tvar Srdce máme v řádku 6 fotografií. Proto bylo potřeba toto chování opravit a bohužel díky komplexitě frameworku to nebylo nikterak jednoduché. Museli jsme pomocí zapouzdření upravit metody ve tříd, která slouží jako zdroj dat pro zobrazovač náhledů, dále jsme si museli vytvořit podtřídu zobrazovače náhledů a nakonec i podtřídu pro obrázky. V každé z těchto komponent se totiž skládala nějaká část mozaiky, která dohromady skládá kýžený výsledek.
59
Kapitola
Ověření funkcionalit Poté co byla aplikace naprogramována do „Beta verze“ a všechny její funkce fungují a jsou potřebné pouze drobné změny na uživatelském rozhraní, bylo ji potřeba nechat otestovat jinými uživateli a poznamenávat si jejich poznatky.
5.1
Testování uživatelského rozhraní
Přestože v době testování bylo uživatelské rozhraní na svém začátku a pouze v základní fázi, oceňovali uživatelé jeho jednoduchost a přímočarost. Zároveň oceňovali, jak přes jeho jednoduchost aplikace disponuje funkcemi, které jsou vždy dostupné a vždy na místě, kde by je hledali. Přestože aplikace v době testování neobsahovala obrazovku s tipy a triky jak správně fotit, aplikace jim přišla jednoduchá a nejvíc si pochvalovali samotný proces focení. Moc se jim líbilo, jak člověk na obrazovce telefonu vidí skutečnou předlohu v podobě člověka, aplikace jim tím přišla mnohem uživatelsky přívětivější. Zároveň ocenili grafickou podobu předlohy a jejího zobrazení na displeji. Na druhou stranu se jim moc nezamlouvala grafická podoba uživatelského rozhraní, která v době testování nebyla moc lákavá a je opravdu třeba ji vylepšit. Ať se již jedná o barvy či obrázky nebo použité ikonky, právě v tomto má aplikace zatím nedostatky a měla by podobu grafického rozhraní vylepšit.
61
5
5. Ověření funkcionalit
5.2
Testování funkcionalit
Uživatelé si při testování velmi pochvalovali předposlední obrazovku, kde uživatel vidí koláž v podobě miniatur jednotlivých fotografií seskládaných tak, aby tvořili výslednou fotografii a mají ještě možnost si fotografie naposledy prohlédnout a případně vyfotit znovu. Co je ale mnohem důležitější, uživatelé byli spokojeni s podobou výsledných fotografií. Udělalo to na ně velký dojem a moc se jim líbilo, jak jednoduché vlastně bylo si nafotit takovou hezkou fotografii, kterou hned můžou někam poslat. Čekali, že výsledek z aplikace bude odpovídat předloze, ale nejvíce je těšilo, že dobrého výsledku dosáhli i při prvním použití aplikace a že je aplikace celým procesem hezky provedla a jediné co museli udělat, bylo při focení zabrat stejný postoj, jako předlohová fotografie a ve chvíli, kdy se na displeji shoduje postoj předlohy s postojem fotografované osoby, stačí jen zmáčknout tlačítko. S nekvalitním fotoaparátem, kterým mobilní zařízení disponují, se výrazně snižuje kvalita výsledných fotografií vzhledem k okolním podmínkám, nejlepší kvalitu fotografií docílíme focením za jasného denního světla. Výsledek nezdařilé fotografie focené za šera se nachází v příloze A. S výsledkem byli uživatelé spokojení a přidali pár nápadů na další funkce a tvary, o které by se aplikace dala později rozšířit.
5.3
Ověření požadavků
V kapitole Návrh aplikace jsem nadefinoval funkční i nefunkční požadavky, které jsem všechny během implementace aplikace splnil. Aplikace je tedy hotová v plném rozsahu zadání, pouze s drobnými nedodělky na straně uživatelského rozhraní. Jednotlivé klíčové obrazovky jsou vidět v kapitole realizace. Výsledné obrázky z testování porovnané s obrázky z ateliéru, se nahází v příloze A.
62
Závěr Závěrem bych chtěl zmínit, že i přes drobné nesnáze a problémy především při implementaci se mi podařilo aplikaci dokončit v celém rozsahu a jsem rád, že i první uživatelské testy dopadly dobře, i když je potřeba se z nich poučit a na některých nedostatcích zapracovat. Aplikace ve výsledku zabrala mnohem více času, než jsem odhadoval při analýze a návrhu. Bylo zde mnoho drobných funkcí a problémů, které zabraly poměrně dost času, stejně tak jako samotné skládání tvarů bylo mnohem komplikovanější, než jsem předpokládal. Při práci na této aplikaci jsem se naučil hodně nových věcí a aplikoval jsem mnoho vědomostí získaných po dobu mého studia. Práce mě bavila a jsem z finálního výsledku více než příjemně překvapený, protože aplikace funguje lépe, než jsem původně očekával. Na práci se mi líbila i různorodost. Nejednalo se pouze o psaní kódu nebo pouze o analýzu, ale také o práci s fotografiemi, jejich úpravou, či nafocení požadovaných předloh v ateliéru.
Možná rozšíření do budoucna Při testování jsem dostal od uživatelů některé návrhy, které by mohly tvořit další rozšíření aplikace. Například by se v aplikaci mohla objevit funkce, že by se na výslednou fotografii aplikoval nějaký barevný filtr, což by udělalo výslednou fotografii atraktivnější. Dalším možným rozšířením by mohla být možnost vepsat do fotografie vlastní text, například věnování nebo sdílení do více kanálů či přidání nového tvaru. Nápadů na rozšíření by se dalo najít více, ale záleží, jak si aplikace povede mezi velkou skupinou uživatelů a jestli budou mít o rozšíření zájem, případně zda přijdou s dalšími funkcemi, které by chtěli přidat. 63
Závěr
Spuštění aplikace Krátce po obhajobě bych chtěl aplikaci vydat na oficiálním kanále pro aplikace na této platformě, kterou je Apple App Store. Aplikace bude ke stažení zdarma a já doufám, že si ji stáhne mnoho uživatelů a že si aplikaci oblíbí. A třeba se aplikace stane populární a zařadí se mezi ostatní známé tituly na této platformě.
64
Literatura (1) Adobe: Developing for iOS using Flash Professional. 2011. Dostupné z WWW:
(2) Apple.: iOS Dev Center. 2007. Dostupné z WWW: (3) Apple: AV Foundation Programming Guide. 2010. Dostupné z WWW: (4) Apple: Cocoa Fundamentals Guide. 2010. Dostupné z WWW: (5) Apple: The Objective-C Programming Language. 2011. Dostupné z WWW: (6) Conway, R.: iPhone Programming. Big Nerf Ranch, 2010. (7) Facebook: Three20 Framework documentation. 2009. Dostupné z WWW: (8) Foundation, T. E.: Eclipse.
2011.
Dostupné
z
WWW:
(9) Freeman, F. .: Head First Design Patterns. O’ Reilly, 2004. (10) Jim Arlow, I. N.: UML2 a unifikovaný proces vývoje aplikacís. Computer Press, a.s., 2008. (11) RealSoftware: . Dostupné z WWW: (12) Shed, T. B.: Resize a UIImage the right way. 2008. Dostupné z WWW: 65
Literatura (13) Software, T. D.: iPhone for Programmers, An App-Driven Approach. Prentice Hall, 2010. (14) of Illinois at Urbana-Champaign., U.: The LLVM Compiler Infrastructure. 2007. Dostupné z WWW: (15) Weiner, N.: ShareKit Framework documentation. 2009. Dostupné z WWW:
66
Příloha
Porovnání předloh a výsledných fotografií A.1
Tvar srdce
A.2
Tvar hvězdy
A.3
Živá abeceda
67
A
A. Porovnání předloh a výsledných fotografií
Obrázek A.1: Předloha tvaru srdce vytvořená v ateliéru
68
A.3. Živá abeceda
Obrázek A.2: Výsledný obrázek tvaru srdce vytvořený aplikací
69
A. Porovnání předloh a výsledných fotografií
Obrázek A.3: Další ukázkový obrázek tvaru srdce
Obrázek A.4: Obrázek, na kterém vzhledem k venkovním podmínkám a oděvu nevynikne tvar uplně dokonale.
70
A.3. Živá abeceda
Obrázek A.5: Předloha tvaru hvězdy vytvořená v ateliéru
71
A. Porovnání předloh a výsledných fotografií
Obrázek A.6: Výsledný obrázek tvaru hvězdy vytvořený aplikací
72
A.3. Živá abeceda
Obrázek A.7: Další ukázkový obrázek tvaru hvězdy
73
A. Porovnání předloh a výsledných fotografií
Obrázek A.8: Předloha nápisu „piknik“ vytvořená v ateliéru
Obrázek A.9: Výsledný obrázek nápisu „piknik“ vytvořený aplikací
Obrázek A.10: Předloha nápisu „friends“ vytvořená v ateliéru
Obrázek A.11: Výsledný obrázek nápisu „friends“ vytvořený aplikací, na kterém se projevil vliv okolního počasí a je vidět, jak se zvyšujícím se šerem, kvalita fotografii klesá
74
Příloha
Struktura Tříd
75
B
B. Struktura Tříd
Obrázek B.1: První polovina struktury tříd a souborů
76
Obrázek B.2: Druhá polovina struktury tříd a souborů
77
Příloha
C
Obsah přiloženého CD + + + +
README.txt - soubor se všemi potřebnými informacemi o~obsahu CD thesis_sources - složka obsahuje zdrojové soubory k~výslednému PDF app_sources - složka obsahuje zdrojové kódy aplikace dominik_vesely_bp.pdf - tato práce ve formátu PDF
79