Exportarea unui movie clip ca imagine .jpg sau .png
28.10.2009
In acest tutorial iti voi arata cum poti exporta continutul unui movie clip de pe scena intr-o imagine .jpg sau .png pe calculatorul tau. Pentru aceasta aplicatie vei avea nevoie de Flash CS4 si Flash Player 10 pentru a putea salva imaginea pe disc.
2665 afisari 2 Rating (9 voturi) 40 min

De la aparitia Action Script 3, multi programatori au fost nevoiti sa-si schimbe modul de lucru si abordarea in ceea ce priveste implementarea unei aplicatii Flash. In mod cert, acest proces nu este placut pentru nimeni si lipsa unor functii simple ca getURL poate deveni frustranta. Pe de alta parte, in AS3 poti scrie aplicatii imposibil de realizat in AS2.

Bineinteles, daca scopul tau este sa creezi un banner cu o animatie simpla, atunci n-are sens sa te complici – AS2 este mai mult decat suficient. Daca, in schimb, trebuie sa implementezi un whiteboard sau alte chestii marete, atunci ar fi mai bine sa iti cauti un manual de AS3. In principiu, nu iti recomand sa te limitezi la AS2 doar pentru ca il stapanesti bine si e comod si „caldut” ca o pereche de papuci de casa, ci sa te adaptezi in functie de situatie.

In acest tutorial iti voi arata cum poti salva continutul unui movie clip de pe scena intr-o imagine .jpg sau .png pe calculatorul tau. In primul rand, retine ca aceasta aplicatie a fost implementata in Flash CS4 si are nevoie de Flash Player 10 pentru a putea salva imaginea pe disc. Click aici pentru a vedea cum functioneaza aplicatia.

Pasul 1

In acelasi director, creeaza un fisier .fla nou si un folder classes pentru sursele .as.

Pasul 2

In directorul classes, creeaza doua subdirectoare core (pentru fisierele tale) si adobe. Accesand linkul Download din partea de sus a paginii, descarca fisierele de encodare de imagini si copiaza-le in directorul adobe.

Aplicatia ta ar trebui sa aiba urmatoarea structura:

export_img.fla
classes
    core
    adobe
        images
            BitString.as
            JPGEncoder.as
            PNGEncoder.as

Pasul 3

In directorul core, creeaza un fisier ApplicationMain.as cu urmatorul continut:

package classes.core
{
    import flash.display.Sprite;
    import flash.display.MovieClip;
    import flash.text.TextField;
    
    import flash.geom.Matrix;    
    import flash.display.BitmapData;
    import flash.utils.ByteArray;
    import flash.external.ExternalInterface;
    
    import flash.system.*;
    import flash.net.FileFilter;
    import flash.net.FileReference;
    
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.IOErrorEvent;
    import flash.events.SecurityErrorEvent;
    
    import classes.adobe.images.*;
        
    public function ApplicationMain()
    {
    }
}

Dupa cum poti vedea, am inclus o serie de pachete utile pentru prelucrarea evenimentelor, salvarea fisierelor pe hard disk, bitmap data si clasele adobe pentru encodarea imaginilor.

Pasul 4

In sursa .fla, acceseaza File > Publish Settings (Ctrl+Shift+F12) si fa modificarile de mai jos. In acest mod, constructorul clasei ApplicationMain va fi apelat automat la rularea swf-ului.


Pasul 5

Adauga pe scena un movie clip cu un desen si denumeste-l ca export_mc. Acesta va reprezenta movie clip-ul al carui continut il vei exporta ca .jpg sau .png. In exemplu de mai jos, movie clip-ul contine un fisier .ai si un dreptunghi cu fundal alb.


Pasul 6

Adauga pe scena un buton cu textul "Salveaza", apoi schimba-i numele in export_btn.

Apasarea acestui buton va declansa salvarea imaginii, deci adauga urmatorul cod in constructorul clasei ApplicationMain.

export_btn.addEventListener(MouseEvent.MOUSE_DOWN,  this["btnExportPress"]);

Apoi, tot in clasa ApplicationMain, defineste metoda ce va fi apelata la apasarea butonului:

public function  btnExportPress(event:MouseEvent){}

Pasul 7

Pentru a raporta mesaje, vom folosi un TextField dinamic cu numele msg_txt. Pentru moment, adauga-l pe scena si lasa-l gol.


Pasul 8

Acum avem toate elementele, deci putem sa trecem la scrierea codului. In clasa ApplicationMain vom defini urmatoarele proprietati:

private var _target;     // orice obiect de pe scena
private var _image:ByteArray;    // imaginea ca sir de octeti 
private var _filename = 'bitmapSnapshot.jpg';    // numele fisierului salvat pe disc

De asemenea, in constructor vom initializa membrul _target cu movie clip-ul pe care l-am creat la Pasul 5:

this._target =  this.export_mc;

Pasul 9

E momentul sa scriem functia pentru encodarea imaginii, deci adauga urmatorul cod in clasa ApplicationMain:

public function takeSnapshot():void{
    // preia inaltimea si latimea movie clip-ului pe care il exportam
    var $width = _target.width;
    var $height = _target.height;
                    
    // creeaza un obiect bitmap ce reprezinta imaginea
    var bmd:BitmapData = new BitmapData($width, $height, true, 0xFFFFFF);
    bmd.draw(_target, new Matrix(), null, null, null, false);
            
    // encodeaza in format png sau jpg
    var ext:String = this._filename.substr(-3);
    if (ext == 'png') {
        _image = PNGEncoder.encode(bmd);
    }    
    else if (ext == 'jpg'){
        var jpgEncoder:JPGEncoder = new JPGEncoder(100);
        _image = jpgEncoder.encode(bmd);
    }
}

Dupa cum poti observa, codul de mai sus calculeaza latimea si inaltimea movie clip-ului _target, apoi copiaza continutul acestuia intr-un obiect BitmapData cu aceleasi dimensiuni. In continuare, utilizand clasele adobe, obiectul BitmapData este transformat intr-un sir de octeti ce reprezinta de fapt o imagine .jpg sau .png.

In mod default, extensia este .jpg, dar o poti schimba in .png modificand proprietatea _filename din clasa noastra.

Nu uita ca la apasarea butonului trebuie sa apelezi aceasta functie, deci metoda btnExportPress() trebuie sa contina codul:

takeSnapshot();


 OBS. 1   Daca vrei sa salvezi un movie clip cu border, tine cont ca Flash nu calculeaza corect inaltimea si latimea acestuia, deoarece borderul este centrat pe conturul obiectului. Cu alte cuvinte, daca borderul este de 6px, trebuie sa retii dimensiunea movie clip-ului fara border si sa-i adaugi cate 3 px (adica jumatate din latimea borderului) pentru a afla inaltimea si latimea corecta.

 OBS. 2   Mastile reprezinta o problema pentru ca ele sunt luate in considerare in calculul dimensiunilor. De asemenea, retine ca encodarea are loc pentru coordonate pozitive, deci elementele cu x sau y negativ din _target vor fi ignorate.

 OBS. 3   Pentru formatul jpg sau jpeg, clasele implementate de adobe encodeaza imaginea transformand fiecare pixel din RGB in YCbCr (unde Y reprezinta luminozitatea, iar Cb si Cr sunt componentele cromatice). Imaginea este compusa octet cu octet, pornind de la headere si continuand cu octetii pentru fiecare pixel. Daca vrei sa schimbi modul de encodare al imaginii, de exemplu in Grayscale, ar trebui sa modifici headerele si sa renunti la cei doi octeti de culoare (Cb si Cr), ceea ce de fapt inseamna rescrierea algoritmului de conversie.


Pasul 10

Aproape am terminat, ceea ce mai trebuie sa faci este sa salvezi imaginea pe disc. Pentru a preveni o eroare, trebuie ca mai intai sa aflam versiunea playerului flash:

public function getFlashPlayerVersion(){
    // Afla versiunea playerului cu functia globala getVersion()
    var versionNumber:String = Capabilities.version;
            
    // Versiunea este o lista de elemente despartite prin ","
    var versionArray:Array = versionNumber.split(",");
    var length:Number = versionArray.length;
            
    // Versiunea principala contine si tipul sistemului de operare
    // deci o impartim in doua pentru a afla numarul principal
    var platformAndVersion:Array = versionArray[0].split(" ");
                        
    var majorVersion:Number = parseInt(platformAndVersion[1]);
    var minorVersion:Number = parseInt(versionArray[1]);
    var buildNumber:Number = parseInt(versionArray[2]);
            
    trace("Platforma: "+platformAndVersion[0]);
    trace("Versiune principala: "+majorVersion);
    trace("Versiune secundara: "+minorVersion);
    trace("Build: "+buildNumber);
    trace("-----");
            
    return majorVersion;
}

Dupa ce ai scris metoda de mai sus, adauga linia urmatoare in functia takeSnapshot():

var flashVersion  = this.getFlashPlayerVersion();

Pasul 11

Utilizand versiunea playerului aflata cu functia getFlashPlayerVersion(), vom raporta un mesaj de eroare daca aceasta este mai mica decat 10. In caz contrar, totul este in regula si putem salva imaginea pe disc, deci adauga codul de mai jos in metoda takeSnapshot():

// daca versiunea e mai mica de 10, afiseaza un mesaj de eroare
if (flashVersion < 10){
    this.msg_txt.text = "Eroare, trebuie sa ai instalat Flash Player 10";
}
// altfel, salveaza imaginea pe hard disk
else{
    var saveFile:FileReference = new FileReference();
    saveFile.addEventListener(Event.COMPLETE, saveCompleteHandler);
    saveFile.addEventListener(Event.CANCEL, saveCancelHandler);
    saveFile.addEventListener(IOErrorEvent.IO_ERROR, saveIOErrorHandler);
    saveFile.save(_image, this._filename);
}

Poti observa ca am adaugat niste handlere pentru anumite evenimente (daca imaginea a fost salvata cu succes, daca s-a apasat butonul Cancel sau daca a survenit o eroare):

private function saveCompleteHandler(event:Event):void{
    event.target.removeEventListener(Event.COMPLETE, saveCompleteHandler);
    event.target.removeEventListener(Event.CANCEL, saveCancelHandler);
    event.target.removeEventListener(IOErrorEvent.IO_ERROR, saveIOErrorHandler);
    
    this.msg_txt.text = "Imaginea a fost salvata";
}
 
private function saveCancelHandler(event:Event):void{
    event.target.removeEventListener(Event.COMPLETE, saveCompleteHandler);
    event.target.removeEventListener(Event.CANCEL, saveCancelHandler);
    event.target.removeEventListener(IOErrorEvent.IO_ERROR, saveIOErrorHandler);
    
    this.msg_txt.text = "Actiune anulata";
}
 
private function saveIOErrorHandler(event:IOErrorEvent):void{
    event.target.removeEventListener(Event.COMPLETE, saveCompleteHandler);
    event.target.removeEventListener(Event.CANCEL, saveCancelHandler);
    event.target.removeEventListener(IOErrorEvent.IO_ERROR, saveIOErrorHandler);
    
    this.msg_txt.text = "Eroare la salvare";
}


 OBS. 4   In cazul in care vrei ca aplicatia sa functioneze si pe versiuni anterioare ale playerului Flash, poti utiliza scripturi .php pentru a incarca (folosind URLRequest) si apoi descarca imaginea de pe server. Problema este ca orice fereastra deschisa din interiorul swf-ului tau va fi interpretata ca un pop-up si este foarte posibil ca ea sa fie blocata de browser.

Poti downloada sursa completa a acestui tutorial daca accesezi pagina de resurse. Nu ezitati sa-mi scrieti daca aveti intrebari.

Copyright © 2008-2010 E-LEARN.ro. Toate drepturile rezervate. Conceput si realizat de Neokinetics Software.