lundi 02.03.2009, 14:00
ByteArray to Bitmap
Par Cédric Tabin - ActionScript - Lien permanent
Dans la dernière révision de Masapi (révision 138), j'ai intégré le support Bitmap pour les données au format binaire chargées via un URLLoader. Toutefois, j'ai du faire une sorte de hack pour arriver à mes fins...
A la base, l'idée est simplement de convertir un ByteArray en Bitmap grâce au Loader. L'AS3 fournit la méthode Loader.loadBytes qui est correspond parfaitement à cela :
function getBitmap(data:ByteArray):Bitmap { var converter:Loader = new Loader(); converter.loadBytes(data); var bmp:Bitmap = converter.content as Bitmap; return bmp; } var myBitmap:Bitmap = getBitmap(myUrlLoader.data); trace(myBitmap); //null
De toute évidence la méthode Loader.loadBytes est asynchrone (il semblerait que ce soit du à des questions de sécurité). Du coup, il faut contourner le problème en utilisant un instance temporaire :
function getBitmap(data:ByteArray):Bitmap { var container:Bitmap = new Bitmap(); var converter:Loader = new Loader(); converter.loadBytes(data); var bmp:Bitmap = converter.content as Bitmap; //... return container; }
Et pour finaliser tout cela, une fois les données parsées grâce au Loader, il suffit de cloner le BitmapData pour le mettre dans l'instance temporaire :
function getBitmap(data:ByteArray):Bitmap { var container:Bitmap = new Bitmap(); var converter:Loader = new Loader(); converter.addEventListener(Event.COMPLETE, onDataParsed); converter.loadBytes(data); function onDataParsed(evt:Event):void { var content:Bitmap = converter.content as Bitmap; var clonedData:BitmapData = content.bitmapData.clone(); container.bitmapData = clonedData; } return container; }
Cette méthodologie permet l'utilisation directe d'un Bitmap à partir d'un ByteArray, mais sans 'contenu'. Il faut donc rester prudent avec son utilisation car il est impossible de jouer avec la hauteur ou la largeur par exemple...
Il me semble avoir bien cherché dans la documentation une manière synchrone de transformer un ByteArray en Bitmap, mais visiblement il n'y a rien qui puisse faire cela
Je vois mal d'autres solutions, à moins de réécrire un parser de données binaire (ce qui ne me semble pas très pertinent).
Si quelqu'un a une idée ou voit une meilleure solution, je suis preneur !
9 commentaires
salut
y'a pas une chance que ça fonctionne avec BitmapData.setPixels()?
Salut,
Eventuellement, mais tu fais face à deux problèmes : la taille (inconnue à l'avance) et la sérialisation (jpg, png, ...). Pour une méthode générique ça ne jouera pas
@++
tiens, ça me rappelle quelque chose...
avec pixel bender ca se fait facilement, il suffis de creer un pjb vide,
j'ai mis un petit test en commentaire sur la doc,
http://help.adobe.com/en_US/AS3LCR/...
Salut,
Ca m'a l'air intéressant ! Mais ça n'enlève pas le problème que doive connaître la taille avant non ?
@++
oui, dans tout les cas, il faut les dimentions de l'image, et les metadata son différents pour chaque format, retour a ton premier commentaire
mettez un écouteur sur le loadinfo du loader et un fois le chargement fini, vous pouvez récupérer les tailles des images.
exemple :
myLoader.addEventListener(Event.COMPLETE, Infos);
myLoader.loadByte(/*ma chaine de caractere*/);
function Infos(e:Event):void{
myLoader.content.width //retourne la largeur de l'image
}
Salut,
Oui, mais le souci est que c'est un appel synchrone... et donc tu n'auras pas directement la donnée quand l'objet t'es retourné. Mais oui effectivement ce passage est obligatoire...
@++
Salut,
Lee Brimelow le fait dans son tuto à l'adresse suivante : http://www.gotoandlearn.com/play?id...
Pour obtenir la largeur et la hauteur du BMP, il faut utiliser la méthode readInt() de la classe ByteArray.