// ottobre 26th, 2007 // 3 Comments » // Sviluppo e tips
La classe BitmapData (flash.display.BitmapData) ci permette di creare e manipolare in piena libertà le immagini tramite Actionscript per la creazione di effetti altrimenti irrealizzabili con i filtri messi a disposizione nell’apposito pannello di Flash.
Un oggetto BitmapData contiene tutte le informazioni sui pixel dell’immagine e può essere assegnato a un MovieClip utilizzando il metodo MovieClip.attachBitmap().
Gli usi possibili della classe BitmapData sono tantissimi e per una trattazione più specifica vi rimando alla guida ufficiale. Io invece mi vorrei soffermare su un uso molto utile di BitmapData nella gestione delle immagini (JPEG, GIF, PNG) caricate esternamente in quei casi in cui si ha il bisogno di riutilizzare più volte le immagini caricate.
Immagino abbiate presente l’utilizzo del metodo MovieClip.attachMovie() per “attaccare” un elemento in libreria a un MovieClip presente sullo stage. Il MovieClip in libreria dovrà essere stato identificato per il Linkage.
In un modo simile possiamo sfruttare il metodo MovieClip.attachBitmap() per gestire, come se le avessimo il libreria pronte all’uso, delle immagini caricate dall’esterno in un determinato momento del nostro movie Flash: vediamo come è possibile ricreare una situazione di questo genere in ActionScript.
Supponiamo che ad un certo istante del nostro movie venga chiamata una funzione che carica N immagini, che per comodità definiremo in un array ma che potrebbero anche essere definite in una struttura XML o altro.
Quindi prendiamo in esame il seguente codice incaricato del caricamento sequenziale delle immagini contenute nella cartella img in un MovieClip temporaneo temp che verrà rimosso al termine di ogni caricamento:
var imgPath = new Array("img/photo1.jpg","img/photo2.jpg");
var count:Number = 0;
function loadImage():Void{
_root.createEmptyMovieClip("temp", _root.getNextHighestDepth());
var mcl = new MovieClipLoader();
var myListener = new Object();
myListener.onLoadInit = function(target_mc) {
target_mc.removeMovieClip();
if(_root.count<_root.imgPath.length-1){
_root.count++;
_root.loadImage();
} else {
trace("Finito");
}
}
mcl.addListener(myListener);
mcl.loadClip(imgPath[count], temp);
}
loadImage();
Penso che la fattura di questa funzione sia comune a molti soprattutto per quanto riguarda l’utilizzo del metodo MovieClipLoader.loadClip() associato all’Event Listener onLoadInit. In pratica la funzione loadImage() viene richiamata da se stessa tante volte quante sono le immagini definite nell’array imgPath. Questa funzione non fa altro che posizionare un MovieClip temporaneo sullo stage e caricarci dentro l’immagine, controllare che sia caricata e poi rimuovere il MovieClip temporaneo. In effetti in questo modo non serve a niente tranne che a mettere in cache le immagini.
Vediamo ora come usare BitmapData per memorizzare le informazioni sulle immagini. Per fare questo dobbiamo importare la classe e per ogni immagine caricata creare un nuovo oggetto BitmapData e poi utilizzare il metodo BitmapData.draw() per “disegnare” una nuova immagine BitmapData a partire da ogni MovieClip temporaneo che nel nostro caso è identificato con target_mc.
import flash.display.BitmapData;
var bData:BitmapData = new BitmapData(target_mc._width, target_mc._height);
bData.draw(target_mc);
Inseriamo questo codice nella funzione e ad ogni ciclo memorizziamo l’oggetto bData in un nuovo array che chiamiamo bmp:
import flash.display.BitmapData;
var imgPath = new Array("img/photo1.jpg","img/photo2.jpg");
var count:Number = 0;
var bmp:Array = new Array();
function loadImage():Void{
_root.createEmptyMovieClip("temp", _root.getNextHighestDepth());
var mcl = new MovieClipLoader();
var myListener = new Object();
myListener.onLoadInit = function(target_mc) {
var bData:BitmapData = new BitmapData(target_mc._width, target_mc._height);
bData.draw(target_mc);
bmp.push(bData);
target_mc.removeMovieClip();
if(_root.count<_root.imgPath.length-1){
_root.count++;
_root.loadImage();
} else {
trace("Finito");
}
}
mcl.addListener(myListener);
mcl.loadClip(imgPath[count], temp);
}
loadImage();
In questo modo le immagini vengono caricate nel MovieClip temporaneo, immagazzinate in un BitmapData ed eliminato il MovieClip temporaneo. Al termine del ciclo di caricamento ora chiamiamo una funzione che visualizzerà le immagini facendo il procedimento inverso: verranno creati dei MovieClip sullo stage tanti quanti i BitmapData registrati e attaccati ad essi le informazioni di ogni BitmapData come se le immagini fossero in libreria con Linkage specificato.
Lo script finale diventa quindi:
import flash.display.BitmapData;
var imgPath = new Array("img/photo1.jpg","img/photo2.jpg");
var count:Number = 0;
var bmp:Array = new Array();
function loadImage():Void{
_root.createEmptyMovieClip("temp", _root.getNextHighestDepth());
var mcl = new MovieClipLoader();
var myListener = new Object();
myListener.onLoadInit = function(target_mc) {
var bData:BitmapData = new BitmapData(target_mc._width, target_mc._height);
bData.draw(target_mc);
bmp.push(bData);
target_mc.removeMovieClip();
if(_root.count<_root.imgPath.length-1){
_root.count++;
_root.loadImage();
} else {
showImages();
}
}
mcl.addListener(myListener);
mcl.loadClip(imgPath[count], temp);
}
loadImage();
function showImages():Void{
for(var i=0; i<bmp.length; i++){
_root.createEmptyMovieClip("copy"+i, _root.getNextHighestDepth())
_root["copy"+i]._x = 200*i;
_root["copy"+i]._y = 200*i;
_root["copy"+i].attachBitmap(bmp[i], 1);
}
}
In qualsiasi momento potrete richiamare e visualizzare i BitmapData semplicemente usando il metodo MovieClip.attachBitmap() come se fosse MovieClip.attachMovie(). Ci sono molti altri aspetti interessanti di questo utilizzo sia legati alle possibilità di smoothing offerte dall’attachBitmap() che dalle innumerevoli possibilità di modifica sulle immagini dal momento che sono dei BitmapData… a voi continuare lo studio.
Spero vi sia stato utile.