JavaScript - HTML5 képfeldolgozás

6. Képpontozó

A fény kifejezést hétköznapi értelemben a látható elektromágneses sugárzás jelenségének leírására használjuk, "szigorúbb megfogalmazás szerint a fény az emberben kialakuló érzetet és észleletet jelöli, amit az optikai sugárzásnak (100nm-1mm) egy szűkebb, látható tartománya (380nm-780nm) képes kiváltani. Ennek a szűkebb tartománynak az egyik végénél az ultraibolyatartomány (100-400nm), a másik végénél az infratartomány (780nm-1mm) helyezkedik el."

"Az emberi szemben a pálcikák és csapok végzik az elektromágneses hullámok érzékelését, míg előbbiek gyenge fényviszonyok mellett és a szem periférikus területein is jelentős érzékenységgel bírnak, addig utóbbiak elsősorban nappali körülmények között, a szem központi részén érzékelik a látható sugárzást. A pálcikák nem képesek a színek megkülönböztetésére, viszont a csapokból 3 féle található, eltérő érzékenységgel: L(λ), M(λ) és S(λ) (L: long - hosszú, M: medium - közepes, S: short - rövid hullámhossz tartományt jelöl). A színes kamerák színképi érzékenysége az emberi szemhez nagyon hasonló módon képzelhető el: a különböző spektrális tartományok érzékeléséért külön szenzorok felelősek. A kamerákból kiolvasható R, G, B (R: red - vörös, G: green - zöld, B: blue - kék) értékek a három szenzor válaszának felelnek meg."[1] Az így kapott digitális képek ábrázolásra többféle színmodell is alkalmas. A monitorok és a televíziók működése az additív színkeverési módra épül, és ennek megfelelően a HTML5 digitális vászna is az RGB modellt használja.

Star Wars R: G: B:
Your browser does not support the HTML5 canvas tag.
Fényerő Kontraszt Átlátszóság

Képpontok szín és átlátszóság kezelése

Készítsünk digitális képek megjelenítésére alkalmas JavaScript kódot, amely a vászonra rajzolt kép színcsatorna, fényerő, kontraszt és átlátszóság beállításait szemlélteti. Az átlátszóság bemutatásához a vásznat tartalmazó cella rendelkezzen saját háttérképpel.

Bemenet: A Csillagok háborúja-trilógia főszereplőnek fotói, a PE-MIK bejáratáról készült digitális kép, valamint a színcsatorna, a fényesség, a kontraszt és az átlátszóság adatok.

Kimenet: A kijelölt digitális kép a beállított módosításokkal.

Változók: A canvas, context változók a vászonműveletekhez, az imgViewer objektum változói a digitális kép kezeléséhez, továbbá az űrlap mezői a paraméterek fogadásához.

Algoritmus: Megszerkesztjük az adatok fogadására alkalmas űrlapot, amelyben elhelyezzük a képek megjelenítésre használt vásznat, majd a Form lenyíló listájára felfűzzük az előkészített képek azonosítóit. Létrehozunk egy imgViewer objektumot, ami elvégzi a képek feltöltését, cseréjét és gondoskodik a Form beállításainak megfelelő képmódosításokról. A vásznon megjelenő kép gyakorlatilag egy olyan adatfolyam lesz, ahol egymást követik a képpontok RGB és Alfa csatornájának byte-jai. Az átlátszóság szemléltetéséhez kihasználjuk a CSS background-image tulajdonságát, és a vászon háttérképeként beillesztjük a PE-MIK bejáratáról készült képet.

Eseménykezelés: Az űrlap onchange() eseményét az imgViewer objektum adjustment metódusa kezeli le, és gondoskodik az űrlapértékeknek megfelelő a képpontértékek beállításáról.

Kedves Bitfaragó jelöltek!

A HTML5 canvas digitális képek kezelését is támogatja. Segítségével könnyen megjeleníthetjük és egyszerű programozási eszközökkel manipulálhatjuk is a képeinket. Ebben a leckében bemutatunk néhány JavaScriptben kódolt képszerkesztési műveletet, amelyek ismeretében már összetettebb feladatok megoldására is vállalkozhattok. A minta feladatok alatti  Próbáld ki! »  gombra kattintással nemcsak megnézhetitek a futási eredményt, hanem mindjárt szerkeszthetitek is a kódot.

1

Színcsatorna és átlátszóság

A digitális kép méretét az x és y irányú képpontok számával adjuk meg. A képpontonként eltárolt bitek száma pedig meghatározza a színmélységet. Ha a vörös, zöld és kék színcsatorna is egy-egy önálló byte-ot foglal le, akkor ebben az esetben 24 bites színmélységről beszélhetünk. Viszont minden képponthoz hozzárendelhetünk egy úgynevezett alfa csatornát is, amivel az átlátszóságot szabályozhatjuk. Ekkor már 24 + 8 = 32 bites színmélységről beszélünk. Az előzőek ismeretében könnyen kiszámolható, hogy egy 800 X 600 képpontból álló kép 32 bites színmélységgel 800*600*32/8= 1,92 MiB méretű lesz.

A canvas drawImage() metódusával helyezhetünk el képet a digitális vászonra. A képpontok adataihoz pedig a getImageData() metódussal juthatunk, ami gyakorlatilag egy byte-folyamot ad vissza. Az egymás után következő byte-ok rendre a képpontok vörös, zöld, kék és alfa csatornáinak értékét tartalmazzák. Ezeket az értékeket egy adekvát algoritmussal módosíthatjuk, majd a putImageData() metódussal vissza is írhatjuk a vászonra.

Figyeljétek meg az alábbi képnézegető scriptben az űrlap beviteli mezőinek, valamint a színkódok és az alfa csatorna értékeinek kezelését.

Megjegyzés: Az átlátszóság használatakor ügyeljetek arra, hogy nem minden fájlformátum tárolja az Alfa csatornán beállított értékeket. A .GIF és .PNG formátumok megőrzik a beállított átlátszóság értéket, de a .JPG érhető okok miatt nem.

« Előző | Lap eleje

2

Képméretezés, vágás, nyírás

A vászonra a drawImage() metódussal rajzolhatjuk fel a kiválasztott képünket. A legegyszerűbb esetben a kép elérési útjának és a rajzolási koordináták megadásával már meg is jelenik a képünk az tárolt méretben. Ám a drawImage() metódus paraméterei átdefiniálhatók. A programozási gyakorlatban biztos találkoztatok már az overloading kifejezéssel. Nos, ha drawImage('kép neve',x,y, width, height) metódust újabb két paraméterrel kiegészítve hívjuk meg, akkor a width értékkel a rajzolási szélességet, a height értékkel pedig a rajzolási magasságot tudjuk szabályozni.

Ha további négy paraméterrel megtoldjuk a drawImage() metódus paraméterlistáját, akkor a kijelölt képről az általunk megadott pozíciótól a megadott méretű képrészletet tudjuk kiemelni, amit a vásznon az utolsó négy paraméterrel megjelölt pozícióban a megadott méretben helyez el a metódus. Rövidebben: drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight)

A canvas minden objektumához tartozik egy transzformációs mátrix. A nyírás műveletéhez a transform() metódust vehetjük igénybe, ami az aktuális transzformációs mátrixot cseréli le. A paraméterek értelmezése röviden: context.transform (x skála, x ferdítés, y ferdítés, y skála, x elmozgatás, y elmozgatás). Az eredeti állapot visszaállítását a setTransform() metódussal tudjuk elvégezni.

« Előző | Lap eleje

3

Tükrözés, elforgatás

A canvas scale() metódusa az aktuális rajz méretezését végzi el, és hatása minden jövőbeni rajzolási műveletre érvényes lesz. A rajzolási pozíciót is skálázza. A scale(2,2) nemcsak a méretet kétszerezi, hanem kétszer olyan távolságra is helyezi el a következő rajzelemet a vászon bal felső sarkától. Vízszintes tükrözésnél a scale(-1, 1) metódussal a jobb oldalról rajzolhatjuk ki a képet, ha előbb a translate() metódussal a rajzolási eltolást a canvas jobb felső sarkához illesztettük.

Az elforgatáshoz a rotate() metódusra lesz szükségünk, amely a paraméterként radiánban megadott szöggel forgatja el a következő rajzelemet. Ügyeljünk a rajzolási pozíció eltolásának megadására is.

« Előző | Lap eleje

4

Animáció kódolása

"De mit is értünk animáció alatt? Maga az animáció szó, a latin "anima" vagyis lélek szóból ered. Ez arra utal, hogy az animáció készítése során lelket adunk, lélekkel töltjük meg az élettelen tárgyakat, legyenek azok bábok vagy akár vonalak. Az animálás során állókép-sorozatokat készítünk, amelyeket ha kellő gyorsasággal egymás után levetítünk – a szemünk tehetetlensége miatt – mozgásélményben lesz részünk. Az animációval több információt közölhetünk, mint egy statikus képpel, de ne feledjük, hogy az animáció megjelenítéséhez, lejátszásához több erőforrás szükségeltetik a megjelenítő eszköz (pl. számítógép, okostelefon, iPad) részéről."[2]

A mintaprogramban egy 65x65 pixeles PNG képet mozgatunk a vásznon 100ms-os időközönként. A kép kezdő pozícióit véletlenszám-generátorral állítjuk elő, ezt követően a beállított lépéshosszal változtatjuk a kép pozíciót, a canvas szélén pedig gondoskodunk az irányváltásról. Egy apró trükk erejéig kihasználtuk a CSS background-image opcióját a canvas hátterének beállításához, ami az NGC 6559 csillagképet mutatja.

« Előző | Lap eleje

5

Egérpozicionálás és eseménykezelés

A HTML DOM események lehetővé teszik, hogy különböző JavaScript eseménykezelő utasításokat kapcsoljunk a HTML dokumentum elemeihez. Az események alapesetben függvényhívásokat kezdeményeznek, melyek csak az esemény bekövetkezésekor hajtódnak végre. Az eseménymodellt a W3C által szabványosított DOM Level 2 mutatja be, amely 9 egéreseményt szabályoz. A mintaprogramunkban a mousemove és mouseleave eseményeket használjuk fel úgy, hogy a DOM addEventListener() metódusával a canvas-hoz kapcsoljuk a saját eseménykezelő függvényünket.

Természetesen a canvas HTML tag-jében az onmousemove és onmouseleave attribútummal is megoldható lenne az eseménykezelő függvény felkapcsolása, de mi itt most tisztán a JavaScript kódra támaszkodtunk. Az egér képernyő pozícióját az eseményparaméter clientX és clientY értéke ugyan megadja, de nekünk a vásznon belüli relatív pozícióra lenne szükségünk. Ehhez a canvas.getBoundingClientRect() metódus visszaadott értékeit kell felhasználnunk, amelyekből kiolvashatók a canvas bal felső sarkának koordinátái. Most már nincs más dolgunk, mint a kiszámított egérpozícióban elvégezzük a tervezett képszerkesztési műveleteket. Jelen esetben egy 60x60 pixeles területet felnagyítunk 100x100 pixelesre. Mivel csak a vászon feletti manipulációt figyeljük, ezért a felület elhagyását a mouseleave esemény bekövetkezésekor szintén le kell még kezelnünk.

« Előző | Lap eleje

6

Oldd meg a feladatokat!

A képpontok birodalmában tett kirándulásunk folyatatásaként lenne még néhány érdekes feladat, melyek megoldásával értékes pontokat gyűjthettek a verseny következő fordulójához. A könnyebb kezelhetőség érdekében a megoldást a feladatok előtti  kék azonosítóval  megegyező nevű könyvtárban dolgozzátok ki. A beküldött HTML kód elején a csapat logója és neve, alatta a feladat azonosítója, és szövege jelenjen meg sötét háttérrel és világos betűkkel. Ezt követően már csak a megoldást kell ügyesen kódolnotok. Az elkészült megoldásokat gyűjtsétek össze a csapat nevével megegyező nevű könyvtárban, majd tömörítve töltsétek fel a honlapra!

Beküldhető feladatok 2014:

  1.  B3-2014-EGY05  A Star Wars története réges-régen, egy messzi-messzi galaxisban játszódik. A Galaktikus Köztársaság békéjét és rendjét Jedi lovagok őrzik. Minden Jedi lovag saját maga készíti fénykardját, ez a végső próba, hogy lovagok lehessenek. A HTML5 canvas tulajdonságainak ismeretében tervezzétek meg a JS2014-B3 típusú virtuális fénykardot:
    1. A markolat hossza 150 pixel. A markolatból gombnyomással ugrasztható ki a penge, illetve oda zárható vissza.
    2. Erőörvénygyűrű a markolat fölött helyezkedik el, és tartalmazza a szabályzókat. Méretére nincs megkötés, de nem akadályozhatja a Jedi lovagot a harcban.
    3. A pengehossz-szabályzó egy csavar, és minél többet tekerünk rajta, annál hosszabb lesz a penge. A penge hossza maximum 600 pixel.
    4. Pengeerő-szabályzó a penge erejét határozza meg. Hasonló csavar, mint a pengehossz szabályzó. A korai fénykardokon még nem létezett. A JS2014-B3 típusnál ez a 20 és 40 pixel között állítható pengeszélességet módosítja.
    5. A kristály határozza meg a penge színét, ami a vörösből a zöldön át egészen a kékig változhat. A választható kristály színe, fényereje, kontrasztja és átlátszósága szabályozható legyen.
    6. A vásznon megjelenő fénykard opcionálisan tükrözhető és elforgatható legyen.

    1000 0000|2 pont

  2.  B3-2014-EGY06  Készítsetek egyszerű reflex játékot JavaScript kódban! A HTML dokumentumban helyezzetek el egy legalább 400x600 pixel méretű canvas objektumot, amely egy kisebb maximum 80x80 pixel méretű képet tartalmaz valamelyik Sith lovagról. A képre kattintáskor az a vászon egy véletlen számmal generált pozíciójára ugrik. A program alapértelmezésben 10 másodpercig számolja a sikeres kattintásokat. Egészítsétek ki a kódot egy űrlappal, ahol a vászon, a megjelenített kép mérete és a játékidő módosítható, továbbá a játékhoz használt kép cserélhető.

    0100 0000|2 pont

  3.  B3-2014-EGY07  A Galaktikus Birodalomban lovagjai űrsikló versenyen mérik össze harci eszközeik erejét, ahol a csillagközi térben legalább három különböző típusú (Imperial, Jedi T-6, Republic attack) űrsikló startol, és változó gyorsulással véletlenszám-generátorral megadott távolságokat tesz meg. A verseny a fogadás megtételével indul, és a kiválasztott csillagkép határának elérésekor ér véget. Az eredmény és a fogadás kiértékelése a futam végén jelenjen meg.

    0100 0000|2 pont

  4.  B3-2014-EGY08  Az NGC 6559 nevű galaxis lakói három különböző típusba tartoznak. Az első az átlagos, a kis engiszik 67%-a születik ilyennek. Jellemző tulajdonságuk, hogy nagyon függnek a többiektől, jókedvszintjük születéskor bármilyen értéket (0-100) felvehet, és minden találkozáskor igazodnak a másik jókedvszintjéhez. A második típus az optimista, születéskor 1/5 valószínűséggel lesznek ilyenek az engiszik. Minimum 60-as jókedvszinttel születnek, és ez soha sem változik. A többi engiszi pesszimista. Kezdetben 20 alatt van a jókedvszintjük, és minden optimistával való találkozáskor feleződik. Mindhárom típus mozgása könnyed, a galaxison belül bármelyik pillanatban bárhol felbukkanhatnak.
    Optimista o1 Átlagos a1 Pesszimista p1
    Optimista o2 =o1 =(a1+o2)/2 =p1/2
    Átlagos a2 =o1 =(a2+a1)/2 =p1
    Pesszimista p2 =o1 =(a1+p2)/2 =p1
    Tervezzétek meg az NGC osztályt! Szimuláljátok az NGC 6559 galaxis lakóinak életét, és jelenítsétek meg vizuálisan. Használhattok smile-kat a három típusú engiszi megjelenítéséhez, vagy tervezhettek saját ikonokat is. Minden lépés után tároljátok a lakók állapotát, és számoljátok ki a galaxis összjókedvét.

    1000 0000|2 pont

« Előző | Lap eleje

Hivatkozások, felhasznált források

[1] Czúni László - Tanács Attila: Képi információ mérése, Typotex, 2011 (pdf)

[2] Abonyi-Tóth Andor - Nagy Norbert - Regős Ákos: A multimédia-alkalmazások elemei: a képek

[3] Pluhár Zsuzsa: Webanimáció

[4] HTML Canvas Reference

[5] HTML5 Canvas Tutorials

[6] Horváth Győző: Bevezetés a kliens- és szerveroldali webalkalmazások készítésébe

[7] Browser photo editor: http://apps.pixlr.com/editor/

[8] CodeMirror: Theme Demo

[9] Hivatalos Star Wars oldal és a Magyar Star Wars Archívum