Una delle maggiori limitazioni di Flash, dovuta essenzialmente alla sicurezza, è sempre stata quella della lettura e soprattutto del salvataggio di file: per queste operazioni si affiancava all'applicazione Flash un supporto lato server.
La classe FileReference del Flash Player 10 - che già veniva usata per l'upload in combinata con linguaggi server-side nelle ultime versioni - è stata potenziata ed è ora possibile usarla anche per salvare dati sul computer dell'utente senza la necessità di passare da altri linguaggi.
Ovviamente per motivi di sicurezza l'operazione deve essere confermata dall'utente, che sceglierà anche il percorso locale del file.
Si tratta di una caratteristica molto interessante, specie se unita con alcune librerie esterne come la Actionscript 3 Core Library, sviluppata da Adobe e che include delle classi per l'encoding in JPG o in PNG.
L'accoppiata ci permetterebbe, ad esempio, di prendere uno screenshot della nostra applicazione (o di un componente) e salvarlo in formato JPG o PNG sul pc dell'utente. Per ottenere lo stesso comportamento con Flash CS3 e Flash Player 9 avremmo dovuto passare le informazioni dallo stage ad una applicazione lato server, che si sarebbe poi occupata di convertire i dati ricevuti da Flash in immagine.
Ora tutto è molto più semplice e in questo articolo creeremo una piccola applicazione che permetterà all'utente di caricare un'immagine, elaborarla in Flash e salvarla poi modificata, il tutto sfruttando la classe FileReference e la Actionscript 3 Core Library.
L'applicazione che svilupperemo nell'articolo
Caricare un file dal pc dell'utente
È bene precisare innanzitutto che il caricamento del file non comporta un parallelo upload del file sul server, ma il file viene letto e i caricato all'interno del player in un oggetto di tipo ByteArray
, classe anch'essa introdotta in Actionscript 3. Per motivi di sicurezza infatti il player riceve solo il nome e i contenuti del file ma non ad esempio il path in cui è memorizzato.
Anzitutto creiamo un pulsante sul nostro stage e gli diamo nome istanza carica
; questo pulsante dovrà aprire la finestra di scelta del file da caricare nella nostra applicazione. Il codice da utilizzare è il seguente:
I commenti dovrebbero essere sufficienti a comprendere il codice, fin qui non c'è nulla di complesso, semplicemente sfruttiamo il metodo browse
FileReference
filtro
FileFilter
jpg
gif
png
Una volta che l'utente avrà selezionato un file, sarà chiamata la funzione scegliFile
caricare i dati del file nel player
function scegliFile(evt) { // rimuoviamo l'evento di scelta file non più necessario _loadFile.removeEventListener(Event.SELECT, scegliFile); // creiamo il listener per l'evento COMPLETE che verrà // lanciato una volta completato il caricamento del file _loadFile.addEventListener(Event.COMPLETE, fileCaricato); // carichiamo il file all'interno del player _loadFile.load(); } function fileCaricato(evt:Event) { // azioni da eseguire a caricamento completato }
Questa funzione carica il file grazie al metodo load
COMPLETE
fileCaricato
Leggere il file caricato in memoria
Esaminiamo ora come leggere i dati caricati. L'oggetto FileReference
possiede la proprietà 'data'di tipo ByteArray
che contiene i dati binari del file selezionato dall'utente. Quindi, per utilizzare questi dati, possiamo sfruttare i metodi della classe ByteArray
.
Nel nostro caso abbiamo a che fare con un file jpg
, gif
o png
, quindi dati direttamente interpretabili dal dal Flash Player. Questo ci evita la necessità di implementare un parser intermedio e ci permette di limitarci a mostrare l'immagine caricata sullo stage.
Anche questa volta facciamo uso di un evento, infatti utilizziamo un oggetto Loader
per ottenere i dati contenuti nell'oggetto _loadFile
e attendiamo che il trasferimento sia concluso.
Dopo aver fatto pulizia del listener non più necessario, creiamo il nostro oggetto Loader
loadBytes
load
Al termine del caricamento, sarà scatenato l'evento COMPLETE
immaginePronta
Utilizziamo proprio questo sprite per modificare graficamente l'immagine, non sarebbe infatti possibile operare direttamente sul Loader
// dichiariamo la variabile relativa allo sprite var contenitore:Sprite; function immaginePronta(evt:Event) { // rimuoviamo il listener non pu necessario LoaderInfo(evt.target).removeEventListener(Event.COMPLETE,immaginePronta); // creiamo lo sprite contenitore = new Sprite(); // aggiungiamo l'immagine caricata allo sprite contenitore.addChild(evt.target.content); // aggiungiamo lo sprite allo stage addChild(contenitore); }
Anche questa volta rimuoviamo il listener, ma in questo caso per poter rimuovere l'evento abbiamo dovuto ricavare il target dell'evento come oggetto LoaderInfo
Il resto è molto semplice: dichiariamo il contenitore
Sprite
content
Potremmo voler applicare un ridimensionamento dell'immagine
width
height
contenitore
Modifica dell'immagine
Proprio l'oggetto contenitore
sarà quello che sfrutteremo anche per applicare le altre modifiche alla nostra immagine. Poichè scopo dell'articolo è vedere il caricamento e il salvataggio del file, non faremo particolari operazioni sull'immagine ma ovviamente si può ampliare a proprio piacimento l'applicazione.
In questo caso ci limteremo a convertire l'immagine in scala di grigio, sfruttando il ColorMatrixFilter
; anche questa opzione la associamo ad un pulsante (con nome istanza modifica
).
Salvare l'immagine modificata
Eccoci quindi alla novità più interessante, ovvero la possibilità di salvare il file. In questo caso, trattandosi di un'immagine dovremo ricavare l'immagine modificata in scala di grigi, convertirla grazie all'encoder della Actionscript 3 Core Library e infine salvarla, ovviamente per altri file e altri formati i passaggi "pre-salvataggio" potrebbero variare.
Esaminiamo il codice per questi passaggi, considerando che l'unico "fisso" da riusare anche in altri casi per salvare un file sarà solo quello relativo al nome del file all'oggetto FileReference salvaFile
.
Per prima cosa abbiamo importato il JPGEncoder
JPGEncoder
salvaImmagine
salva
Per prima cosa creiamo un oggetto BitmapData
contenitore
contenitore
Dopo aver preparato l'immagine, impostiamo l'oggetto immagineCodificata
ByteArray
JPGEncoder
85
1
100
_gray
.jpg
expNomeFile
Come ultima operazione, creiamo l'oggetto salvaFile
FileReference
save
browser
save
Conclusioni
Abbiamo visto come la classe FileReference sia stata ulteriormente potenziata, inoltre grazie all'abbinamento con la classe ByteArray permette di estendere notevolmente le feature del player (ad esempio recentemente Lee Brimelow ha riportato sul suo blog alcuni esempi tra cui una classe per caricare file PSD in Flash). Queste caratteristiche aumentano sempre più le potenzialità di Flash in campo RIA, inoltre librerie come la Actionscript 3 Core Library consentono di eseguire facilmente operazioni come l'encoding in PNG o in JPEG, usando poche righe di codice.
La possibilità di caricare e salvare file senza l'ausilio di linguaggi server-side consente migliori performance (il passaggio dell'immagine al linguaggio server-side e il salvataggio tramite le librerie grafiche di quest'ultimo è più complesso del gestire il tutto all'interno del player) e permettono anche una più semplice diffusione dei propri lavori: prima del Flash Player 10 sarebbe stato necessario un hosting con supporto ASP, PHP o altro per supportare questo tipo di applicazione, mentre ora può essere usato praticamente qualsiasi hosting.