Ondřej Brichta 24.10.2005
Nová třída BitmapData v sobě skrývá obrovský potenciál využití. Dnes nakoukneme pod pokličku této významné třídy a ukážeme si zajímavou metodu, která umožňuje kopírovat obrázky pixel po pixelu.
Tato třída se svými metodami a funkcemi přináší do flashových animací opravdovou revoluci. Už jen tím, že díky ní máme možnost významně snížit zatížení procesoru, když vektorové objekty překreslíme do jejich bitmapové reprezentace.
Všechny metody, které s sebou tato třída přináší, si teď vysvětlovat nebudeme, zaměříme se pouze na jednu, nazvanou „copyPixels“. Jak již název napovídá, umožňuje nám kopírovat pixely. Jedná se o vynikající metodu, díky níž můžeme velice snadno „rozřezat“ obrazovou předlohu na menší kousky, vložit je do klipů a dále s nimi pracovat.
Předlohou může být jak rastrový tak vektorový obrázek, přímo vytvořený v prostředí Flashe. Navíc zde můžeme aplikovat průhlednou masku, pomocí které určíme okraje kopírované oblasti pomocí průhledného objektu.
Jak již bylo řečeno, tato metoda umožňuje kopírování zdrojového obrázku pixel po pixelu. Samozřejmě, že má i své parametry, na které se nyní podíváme podrobněji:
flash.display.BitmapData)
Vyzkoušíme si nyní, jakým způsobem lze novu metodu využít. Na scénu si vložíme fotku, ze které budeme postupně „vyřezávat“ myší čtyřúhelníky a výsledné objekty budeme moci různě poskládat po ploše.
Vložíme si tedy na scénu nějakou fotografii, nebo obrázek (ke stažení zde). Vložený obrázek převedeme na MC (klikneme na něj pravým tlačítkem myši a vybereme „Convert to Symbol“) a objekt zarovnáme do levého horního rohu scény.
Otevřeme si knihovnu symbolů a klikneme pravým tlačítkem na vložený objekt obrázek. Z menu zvolíme „Linkage“:

V zobrazeném okně zaškrtneme „Export for ActionScript“ a do pole „Identifier“ napíšeme název objektu, pod kterým jej můžeme na scénu pomocí AS importovat. V naší ukázce jsme zvolili název “houbicka“.

Objekt máme připravený, budeme se věnovat psaní ActionScriptu. Otevřeme si panel akcí pro první snímek časové osy a napíšeme sem první část kódu:
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.filters.DropShadowFilter;
num = 1;
this.onMouseDown = function() {
startX = _xmouse;
startY = _ymouse;
draws = true;
};
this.onMouseUp = function() {
finX = _xmouse;
finY = _ymouse;
sirka = finX-startX;
vyska = finY-startY;
draws = false;
if (maskaCreated != true) {
maskaCreated = true;
var bmpData:BitmapData = new BitmapData(sirka, vyska, false, 0x00CCCCCC);
var kopieObr = flash.display.BitmapData.loadBitmap("houbicka");
eval("maska"+num).bmp.attachBitmap(bmpData, this.getNextHighestDepth());
bmpData.copyPixels(kopieObr, new Rectangle(startX, startY, sirka, vyska), new Point(0, 0));
stin(eval("maska"+num));
}
eval("maska"+num).onPress = function() {
startDrg();
};
eval("maska"+num).onRelease = function() {
stopDrag();
};
};
Nejdříve importujeme některé potřebné objekty, které využijeme při manipulaci s bitmapovými objekty.
Budeme chtít, aby se tažením myši na scéně vytvořil obdélník, který bude tvořit „masku“, pomocí které vyřízneme z kresby příslušnou část. Proto musíme určit při kliknutí myši, od kterého bodu začneme kreslit. To nám obstarají proměnné, které si naplníme při události stisknutí tlačítka myši.
Při uvolnění myši chceme, aby se vytvořila kopie zdrojového obrázku. Použijeme tedy metodu „copyPixels“. Aby vše správně fungovalo, musí být zdrojový a cílový objekt ze třídy „bitmapData“. To zajistíme tím, že si vytvoříme jeden objekt příslušné třídy, nazvaný „bmpData“, do kterého později překopírujeme obsah druhého, který jsme pojmenovali „kopieObr“. Do objektu „kopieObr“ vložíme z knihovny náš obrázek. Tento objekt bude uložen v paměti a budeme jej používat pouze pro vytvoření výřezů, nebude se tedy objevovat na scéně.
Následuje vložení objektu „bmpData“ do klipu v masce a pak už jen provedeme překopírování části ze vzorového obrázku na scénu. Nakonec, po dokončení kopírování, přidáme ke klipu filtr, kterým vytvoříme stín výřezu.
Protože chceme s výřezy pohybovat, musíme každému MC „maska1“, „maska2“ … přiřadit příslušnou funkci pro přetahování, kterou si definujeme v další části skriptu:
this.onEnterFrame = function() {
if (draws == true && maskaCreated != true) {
this.createEmptyMovieClip("maska"+num, num);
eval("maska"+num).lineStyle(2, 0x000000, 100, true, "none", "round", "round", 1);
eval("maska"+num).beginFill(0xFFFFFF, 30);
eval("maska"+num).moveTo(startX, startY);
eval("maska"+num).lineTo(_xmouse, startY);
eval("maska"+num).lineTo(_xmouse, _ymouse);
eval("maska"+num).lineTo(startX, _ymouse);
eval("maska"+num).lineTo(startX, startY);
eval("maska"+num).endFill();
eval("maska"+num).createEmptyMovieClip("bmp", eval("maska"+num).getNextHighestDepth());
eval("maska"+num).bmp._x = startX;
eval("maska"+num).bmp._y = startY;
}
};
stin = function (cil) {
vzdalenost = 10;
uhel = 45;
barva = 0x000000;
pruhlednost = .8;
rozmazX = 10;
rozmazY = 10;
sila = 1;
kvalita = 2;
var filter:DropShadowFilter = new DropShadowFilter(vzdalenost, uhel, barva, pruhlednost, rozmazX, rozmazY, sila, kvalita);
var filterArray:Array = new Array();
filterArray.push(filter);
cil.filters = filterArray;
};
startDrg = function () {
xn = 1;
do {
if (eval("maska"+xn).hitTest(_xmouse, _ymouse, true)) {
eval("maska"+xn).startDrag();
}
xn++;
} while (xn<num+1);
};
Nejdříve si ale musíme vytvořit funkce, pomocí kterých budeme kreslit onen čtyřúhelník. Využijeme přitom událost „onEnterFrame“, kde nejdříve testujeme, jestli pořád ještě táhneme s myší a chceme tedy kreslit objekt čtyřúhelníka a jestli jsme už náhodou masku nevytvořili. Pokud jsme podmínky splnili, vytvoříme si MC „maska“ s indexem podle počtu vytvořených výřezů a začneme v něm kreslit čtyřúhelník.
Dokud máme stisknuté tlačítko myši, neustále překreslujeme původní MC. Po uvolnění tlačítka myši se provede překopírování vzorového obrázku do vytvořeného MC. Tuto funkci jsme si vytvořili v předcházející části.
Následují dvě funkce. První funkcí si vytvoříme stín výřezu. Pomocí druhé funkce určíme, nad kterým objektem se právě kurzor myši, abychom věděli, který objekt máme přetahovat.
Posledním krokem je vytvoření tlačítka, které nám umožní, po vytvoření výřezu, pokračovat a zkopírovat další označenou část z obrázku. Umístíme tedy tlačítko na scénu a přiřadíme mu následující akci:
on (release) {
maskaCreated = false;
num++;
}
Resetujeme proměnnou „maskaCreated“ a pomocí proměnné „num“ zvýšíme číslo, které určuje index aktuálně vytvořeného výřezu.
Nyní si můžeme výslednou animaci otestovat. Určitě zde narazíme na nedostatky, především se jedná o situaci, kdy tažením myši vytvoříme záporné hodnoty rozměrů čtyřúhelníku. Pak se kopie zdrojového obrázku nezobrazí, ale náprava je otázkou několika dalších podmínek.
Výsledek dnešní lekce si můžete prohlédnout zde.
Zdrojový
soubor lekce k dispozici zde.