Bitmapové obarvení objektu

24.10.2011· Autor: Ondřej Brichta· Počet komentářů: 4

Jak přebarvit celý MovieClip pomocí libovolné bitmapy, na to se podíváme v dnešním tutoriálu.

Oříznutá bitmapa podle MovieClipu

O obarvení celého MovieClipu pomocí RGB barvy jsme už několikrát psali (http://www.flash.cz/portal/clanek.aspx?id=837 nebo http://www.flash.cz/portal/clanek.aspx?id=1728 a http://www.flash.cz/portal/clanek.aspx?id=1205) . Jak ale docílit stejného efektu v případě, když budeme chtít cílový MovieClip obarvit bitmapou?

V tomto případě se neobejdeme bez bitmapového překreslení obsahu MovieClipu a následného použití takové bitmapy jako masky pro bitmapu, kterou chceme použít coby výplň.

Jakmile získáme bitmapový „otisk" MovieClipu (metoda draw u BitmapData třídy), máme prakticky dvě možnosti, jak jí využít k ořezu bitmapové výplně:

  1. bitmapa se použije jako maska, která se aplikuje na bitmapu výplně přes obecný způsob maskování - vlastnost „mask" objektů DisplayObject
  2. bitmapa získaná z MovieClipu bude využita u metody „copyPixels" třídy BitmapData, která umožňuje ořez bitmap podle alpha kanálu zdrojové bitmapy (otisku MovieClipu)

 

copyPixels metoda

V naší ukázce si představíme druhou možnost, tedy s využitím copyPixels metody, kterou můžeme využít u třídy BitmapData: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#copyPixels%28%29

Uvedená metoda umožňuje rychlé kopírování pixelů z jedné bitmapy do druhé a její parametry jsou následující:

  • sourceBitmapData - zdrojová bitmapa, ze které budeme pixely kopírovat
  • sourceRect - zdrojový čtyřúhelník, který vymezuje velikost oblasti, kterou chceme kopírovat
  • destPoint - cílový bod, kam se kopírované pixely budou vkládat (nejčastěji bod 0,0)
  • alphaBitmapData - bitmapový objekt, který může obsahovat průhlednost která bude použitá na ořez kopírované bitmapy - toto je pro nás důležitý parametr
  • alphaPoint - analogický bod s destPoint, který určuje počátek kopírování u alphaBitmapData
  • mergeAlpha - při hodnotě true se budou z alphaBitmapData bitmapy kopírovat aplikovat i pixely s průhledností - originální bitmapa bude doplněná o tyto průhledné pixely

 

Pro náš účel je důležitý parametr alphaBitmapData - který bude sloužit pro vložení bitmapového otisku MovieClipu, pokud bude otisk obsahovat průhlednost, bude aplikovaná na kopírované pixely z parametru sourceBitmapData a tím dojde k ořezu bitmapy dle tvaru MovieClipu.

 

ActionScript

Mějme na ploše MovieClip s názvem instance „mc", pak z něj vytvoříme bitmapový otisk do proměnné „bmp":

var m:MovieClip = mc;
var drawMatrix:Matrix = new Matrix();
var objectRectangle:Rectangle = m.getBounds(m);
drawMatrix.tx = -objectRectangle.x;
drawMatrix.ty = -objectRectangle.y;
var bmp:BitmapData = new BitmapData(objectRectangle.width,objectRectangle.height,true,0x00000000);
bmp.draw(m,drawMatrix);

 

Dále máme v knihovně objektů exportovanou bitmapu „stars", kterou využijeme coby bitmapovou masku při kopírování pixelů:

var bitmapFill:BitmapData = new stars();
var startPoint:Point = new Point();
var alphaBitmapMask:BitmapData = bmp.clone();
bmp.copyPixels(bitmapFill,bitmapFill.rect,startPoint,alphaBitmapMask,startPoint,true);

 

Výslednou bitmapu pak můžeme libovolně zpracovat, například umístit na stejné souřadnice jako je MovieClip a tím jej překrýt:

var transformMatrix:Matrix = new Matrix();
transformMatrix.translate(objectRectangle.x,objectRectangle.y);
transformMatrix.scale(m.scaleX,m.scaleY);
transformMatrix.rotate(m.rotation*Math.PI/180);
transformMatrix.translate(m.x,m.y);
var img:Bitmap = new Bitmap(bmp);
img.transform.matrix = transformMatrix;
addChild(img);

 

Transformace se v tomto případě aplikuje z toho důvodu, že metoda draw překreslí originální MovieClip bez jakékoliv deformace, takže výsledný obrázek musíme přes transformaci upravit tak, aby odpovídal původnímu MovieClipu.

 

Po přepsání do třídy bude uvedená funkce sloužit pro vygenerování bitmapového objektu, který je oříznut přesně podle zadaného MovieClipu:

package {
 import flash.display.BitmapData;
 import flash.display.MovieClip;
 import flash.geom.Matrix;
 import flash.geom.Rectangle;
 import flash.geom.Point;
 public class ObjectFill {
 public function ObjectFill() {
 }
 public static function getMaskedBitmapData(bitmapFill:BitmapData,object:MovieClip):BitmapData{
 var drawMatrix:Matrix = new Matrix();
 var objectRectangle:Rectangle = object.getBounds(object);
 drawMatrix.tx = -objectRectangle.x;
 drawMatrix.ty = -objectRectangle.y;
 var bmp:BitmapData = new BitmapData(objectRectangle.width,objectRectangle.height,true,0x00000000);
 bmp.draw(object,drawMatrix);
 var startPoint:Point = new Point();
 var alphaBitmapMask:BitmapData = bmp.clone();
 bmp.copyPixels(bitmapFill,bitmapFill.rect,startPoint,alphaBitmapMask,startPoint,true);
 return bmp.clone();
 }
 }
}

 

Použití je následující:

var m:MovieClip = mc;
var croppedBitmap:BitmapData = ObjectFill.getMaskedBitmapData(new stars(),m)
//
var objectRectangle:Rectangle = m.getBounds(m);
var transformMatrix:Matrix = new Matrix();
transformMatrix.translate(objectRectangle.x,objectRectangle.y);
transformMatrix.scale(m.scaleX,m.scaleY);
transformMatrix.rotate(m.rotation*Math.PI/180);
transformMatrix.translate(m.x,m.y);
var img:Bitmap = new Bitmap(croppedBitmap);
img.transform.matrix = transformMatrix;
addChild(img);

 

Originální MovieClip:

00

Překreslený průhlednou bitmapou:

01

Překreslený neprůhlednou bitmapou:

02

Zdrojové soubory jsou k dispozici zde: data.zip

Ondřej Brichta Vývojář flashových a mobilních AIR aplikací, šéfredaktor Flash.cz, školitel produktů Flash, Flex, Flash Media Server

E-mail: ob(zavinac)obria.cz | Web: http://www.obria.cz |

Motto: <°))))><

Komentáře k článku  
blend modes neznám | 26.10.2011 16:06
Zaujíma neznám | 27.10.2011 13:48
re neznám | 27.10.2011 14:56
Pixel bender neznám | 27.10.2011 15:07

Přihlášení uživatele