Mit der FileReference Klasse kann man auf das Dateisystem des Rechners zugreifen und damit beispielsweise Bilder oder Texte in den Flashplayer laden. Außerdem hat man die Möglichkeit Inhalte aus Flash heraus abzuspeichern.
Siehe hierzu die Adobe Dokumentation
und die Adobe Referenzen
Zu Beginn werden einige Klassen aufgeführt, die nur mit Air möglich sind. So zum Beispiel die Klasse flash.filesystem Unter Beispiele zeige ich Beispiele mit Flash.
Daten auslesen und in Dateien schreiben
Auf dem Pc gibt viele Möglichkeiten auf eine Datei zuzugreifen, Explorer, Startmenü, Tastenkombi etc. Von daher bieten Flash und Air verschiedene Möglichkeiten. Dateien und Verzeichnisse werden aufgerufen über
flash.filesystem.File
Es gibt Verzeichnisse und Dateien. Über die boolsche Eigenschaft isDirectory kann man abrufen, ob es sich um Verzeichnis handelt. Ist der Wert false, kann es nur eine Datei oder Objekt sein.
Die meisten Befehle in Actionscript laufen synchron ab. Das heißt eine Anweisung muss beendet sein, bevor die nächste Anweisung ausgeführt wird. Es gibt aber auch asynchrone Befehle wie beispielsweise die URLLoader load Methode. Asynchrone Programmierung wird in erster Linie dann gebraucht, wenn Vorgänge Zeit beanspruchen, so dass es zu Wartezeiten kommen kann. Bei asynchroner Programmierung ist eine genauerer Planung vonnöten. So lassen sich beispielsweise Ladevorgänge mit Event Listener überwachen.
Die meisten Kernoperationen in Actionscript sind synchron oder asynchron, jedoch nicht beides. In Air gibt es jedoch viele Operationen in einer synchronen und einer asynchronen Variante. Generell sollte man die asynchrone Variante einsetzen, wenn Vorgänge länger dauern könnten.
Man kann asynchrone Dateisystemoperationen mit der cancel() Methode abbrechen. Die cancel() Methode muss auf dem File Objekt aufgerufen werden, welches die Anfrage gestartet hat.
Es folgen 2 Beispiele, welche in der Flash IDE erstellt wurden. In den Beispielen muss eine Instanz der List-Komponente auf der Bühne liegen. Der Instanzname lautet fileList
import flash.filesystem.File; import fl.controls.List; import fl.data.DataProvider; import flash.filesystem.File; import flash.textLayout.elements.ListElement; fileList.dataProvider = new DataProvider(File.documentsDirectory.getDirectoryListing()); fileList.labelField = "name";
import flash.filesystem.File; import fl.controls.List; import fl.data.DataProvider; import flash.filesystem.File; import flashx.textLayout.elements.ListElement; import flash.events.FileListEvent; var docDir:File = File.documentsDirectory; docDir.addEventListener(FileListEvent.DIRECTORY_LISTING, dirListHandler); docDir.getDirectoryListingAsync(); function dirListHandler(evt:FileListEvent):void { fileList.dataProvider = new DataProvider(evt.files); fileList.labelField = "name"; }
Es gibt auf dem Betriebssystem Standardverzeichnisse wie das Desktop Verzeichnis, User-Verzeichnis, Dokument Verzeichnis etc. Über statische Methoden der File Klasse kann man darauf zugreifen, und das sogar platformunabhängig, obwohl die Verzeichnisse in OS2 und Windows an verschiedenen Stellen liegen. Folgende Verweise sind plattformunabhängig:
Verzeichnis | statische Eigenschaft |
---|---|
User Verzeichnis / Home | File.userDirectory |
Document User | File.documentsDirectory |
Desktop | File.desktopDirectory |
Anwendung- oder Installationsverzeichnis der Anwendung (Air Datei, App, fla) | File.applicationDirectory |
Speicherverzeichnes, welches für jede installierte Anwendung angelegt wird | File.applicationStorageDirectory |
Die Eigenschaften sind auch File Objekte. Über die Methode getDirectoryListing kann man beispielsweise das Desktop Verzeichnis synchron abrufen:
var desktopArr:Array = File.desktopDirectory.getDirectoryListing();
Die beiden letzten Eigenschaften kann man auch über ein Argument im Konstruktor des File Objekts bestimmen. So kann man einen Verweis auf ein Anwenundsverzeichnis oder dessen Speicherverzeichnis auch folgendermaßen bestimmen.
var appDir:File = new File("app:/");
var appStor:File = new File("app-storage:/");
Mit der Methode resolvePath() der File Klasse kann man einen absoluten Pfad relativ zum file Objekt auflösen. So kann man beispielsweise auf eine Datei verweisen, die in einem tiefer verschachtelten Unterverzeichnis liegt. Mit folgender Zeile verweist man auf eine Textdatei kosten.txt, in einem Ordner "2013" der im Ordner "rechnungen " der im Ordner Nutzerordner "Dokumente" liegt.
var rechnungen:File = new File.documentsDirectory.resolvePath("rechnungen/2013/kosten.txt");
Der Schrägstrich fungiert als Trennzeichen. Mit 2 Punkten verweiset man auf das nächst höhere Verzeichnis. Backslash ist ein Actionscript für derartige Verweise nicht erlaubt.
Das folgende Beispiel verweist auf den Ordner Eigene Dateien.
var eigeneDateien:File = File.documentsDirectory.resolvePath("..");
Im folgenden Beispiel muss ein dynamisches Textfeld mit Instanzname anzeige auf der Bühne liegen. In dem Textfeld bekommt man alle Dateien angezeigt, die sich in folgendem Ordner befinden "Documents/ Eigene Bilder / schauspieler / neu
import flash.filesystem.File; var bilder:Array = File.documentsDirectory.resolvePath("Eigene Bilder/schauspieler/neu").getDirectoryListing(); for(var i:uint=0; i < bilder.length; i++) { anzeige.appendText(bilder[i].name+"\n"); }
Wenn man in der for-Schleife stattdessen die nächste Codezeile einsetzt bekommt man die Dateien als Elemente eines Arrays. z.B:
schauspieler[0] = "adrian_brody.png";
schauspieler[1] = "adam_sandler.png";
anzeige.appendText("schauspieler\["+i+"\]= "+ "\"" + bilder[i].name +"\";\n");
Relative Pfade kann man auch mit der Methode relativePath() beschaffen. Mit dieser Methode wird ein relativer Pfad von einem Verzeichnis oder einer Datei zu einer anderen ermittelt. Der folgende Code ermittelt den relativen Pfad vom Benutzerverzeichnis zum Dokumentverzeichnis.
var relPath:String = File.userDirectory.getRelativePath(File.documentsDirectory);
Als zweiten Parameter kann man true, eingeben, wenn mittels .. Notaion der Pfad heraus verweisen darf.
Relative Pfade sind wenn möglich vorzuziehen, da sie auf unterschiedlichen Betriebssystemen weniger Poblem bereiten.
var myFile:File = new File("C:/Documents and Settings/");
Wie man sieht kann man auch in Windows Systemen vorwärtsgerichtete Schrägstriche verwenden. Es sind auch Backslashes in diesem Fall möglich, allerdings müssen sie doppelt aufgeführt werden, denn der erste Backslash dient als Escape Zeichen.
File besitzt eine statische Methode File.getRootDirectories(), mit der man ein alle Stammverzeichnisse in einem Array bekommt.
var rootDirs:Array = File.getRootDirectories();
Wie auch immer man auf eine Datei verweist mittels nativePath() kann man sich den absoluten Pfad auf die Datei als String ausgeben lassen. Im folgenden Beispiel muss ein dynamisches Textfeld mit Instanzname anzeige auf der Bühne liegen.
import flash.filesystem.File;
var docs:File = File.documentsDirectory;
anzeige.text = docs.nativePath;
Mit der Methode browseForDirectory() wird ein Dialogfeld geöffnet, mit dem der User ein Verzeichnis auswählen kann, aber keine Dateien.
Ein Hinweistext, der in dem sich öffnenden Fenster angezeigt wird, ist das erste Argument der Methode.
import flash.filesystem.File;
var docs:File = File.documentsDirectory;
docs.browseForDirectory("Wählen Sie ein Verzeichnis");
Wenn das angegebene Verzeichnis nicht existiert, wird das nächsthöhere ausgegeben. Verweist der Pfad auf überhaupt kein gültiges Verzeichnis, wird das Desktopverzeichnis genommen.
browseForOpen() und browseForMultiple() wird für Dateien anstatt Verzeichnisse eingesetzt. Mit der letztgenannten Methode kann man auch meherere Dateien auswählen.
Auch hier muss ein String als Argument übergeben werden, der als Hinweistext oder Bezeichnung des Dialogfeldes erscheint.
In den Methoden browseForOpen und browseForMultiple kann man als zweites Argument einen Filter eingeben, der nur bestimmte Dateitypen zulässt. Es ist ein Array von flash.net.FileFilter Objekten. Das Paket muss importiert werden.
import flash.filesystem.File; import flash.net.FileReference; var docs:File = File.documentsDirectory; var filter:Array = new Array(); filter.push(new FileFilter("JPEG Images", "*.jpg")); filter.push(new FileFilter("GIF Images", "*.gif")); filter.push(new FileFilter("PNG Images", "*.png")); docs.browseForOpenMultiple("Wähle in Bild", filter);
Alternativ könnte man auch folgendermaßen auf alle 3 Bilddateien einen Filter setzen.
filter.push/new FileFilter("All Images", "*.jpg;*.gif;*.png"));
Anstatt Dateien aus dem Verzeichnis zu lesen kann man auch Dateien als Speicherort bestimmen. Man benutzt dazu die Methode browseForSave("Wählen Sie eine Datei");
Man kann also einen Datei oder einen Ordner als Speicherort wählen.
Die zuvor genannten browse-Methoden laufen asynchron.
Nachdem der Benutzter mit den zuvor genannten Methoden eine Datei ausgewählt hat, geschieht folgendes
a) das File Object wird aktualisiert, es verweist auf die ausgewählte Datei.
b) das Select Ereignis wird ausgelöst.
Im folgenden Beispiel muss ein dynamisches Textfeld mit Instanzname "anzeige" auf der Bühne liegen.
import flash.filesystem.File; import flash.net.FileReference; import flash.events.Event; var docs:File = File.documentsDirectory; docs.browseForOpen("Wähle in Bild"); docs.addEventListener(Event.SELECT, fileSelection); function fileSelection(evt:Event):void { var file:File = evt.target as File; anzeige.text = "Datei: "+ file.name; anzeige.appendText(" Pfad: "+ file.nativePath); }
Im folgendem Beispiel wird mit browseForOpenMultiple auf mehrere Dateien zugegriffen. Beachte die Unterschiede in dem folgendem Beispiel.
browseForOpenMultiple
Der Eventtyp ist nicht Event, sondern FileListEvent.SELECT_MULTIPLE
Die ausgewählten Dateien werden in einem Array gespeichert. Über den Parameter der Event Funktion kann man darauf zugreifen.
import flash.filesystem.File; import flash.net.FileReference; import flash.events.Event; var docs:File = File.documentsDirectory; docs.browseForOpen("Wähle in Bild"); docs.addEventListener(Event.SELECT, fileSelection); function fileSelection(evt:Event):void { var file:File = evt.target as File; anzeige.text = "Datei: "+ file.name; anzeige.appendText(" Pfad: "+ file.nativePath); }
Man kann in Air Dateien sowohl aus dem Netz als auch aus dem lokalen Dateisystem laden. Außerdem ermöglicht Air das Schreiben in eine Datei.
In meinem Tipp Thema Loader habe ich beschrieben, wie man Dateien mittels Loader und URLRequest in den Flashplayer läd. Hier stelle ich 2 weitere Klassen vor die von Bedeutung sind, um Daten aus einer Datei zu lesen oder in eine Datei zu schreiben.
URLLoader hier muss die Datei komplett geladen sein, um auf sie zugreifen zu können. Beispielsweise müssen Bilder komplett geladen werden, ehe man mit Hilfe des Complete Ereignis das Bild anzeigen kann.
URLStream, hier kann man schon während des Ladevorgangs auf die Daten zugreifen. Beispielsweise beim Laden von mp3 Dateien.
Mit dem ProgressEvent kann man während das Ladevorgangs eines URLLoader Objekts den Ladevorgang überwachen, aber nicht auf die Bytes zugreifen. Mit einem URLStream Objekt ist dies jedoch möglich.
import flash.filesystem.File; import flash.net.FileReference; import flash.events.Event; import flash.events.ProgressEvent; import flash.net.URLStream; var stream:URLStream = new URLStream(); stream.addEventListener(ProgressEvent.PROGRESS, progressHandler); stream.load(new URLRequest("irgendeineDatei.xml")); function progressHandler(evt:ProgressEvent):void { var stream:URLStream = evt.target as URLStream; while (stream.bytesAvailable) { trace(stream.readByte()); } }
Für das Lesen von Dateien aus einer lokalen Ressource benötigt man das File-Objekt und ein flash.filesystem.FileStream Objekt.
Mit letzterem kann man Daten aus einer Datei lesen und in eine Datei schreiben.
Die Vorgehensweise ist folgende:
File Objekt mit Verweis auf Datei erzeugen:
var file:File = File.desktopDirectory.resolvePath("example.jpg");
Ein neues FileStream Objekt erzeugen:
var fileStream:FileStream = new FileStream();
Mit open() oder openAsync() öffnet man die Datei zum Lesen. Hier werden 2 Parameter benötigt:
a) Verweis auf die Datei (File)
b) und der Wert der Konstanten flash.filesystem.FileMode.READ
fileStream.open(file, FileMode.READ);
Die open Methode läuft synchron, das heißt, die Bytes stehen, während sie geladen werden, zur Verfügung.
Die openAsynch Mehtode hingegen läuft asynchron.
Würde man das folgende Beispiel mit openAsync erzeugen, müsste man den Lesevorgang in einen Progress Funktion einfügen. Wie auch immer, danach sollte man in jedem Fall die Datei mit close() schließen.
import flash.filesystem.File; import flash.net.FileReference; import flash.filesystem.FileStream; import flash.filesystem.FileMode; var file:File = File.desktopDirectory.resolvePath("blabla.txt"); var fileStream:FileStream = new FileStream(); fileStream.open(file, FileMode.READ); while (fileStream.bytesAvailable) { trace(fileStream.readByte()); } fileStream.close();
Letzendlich sind alle Daten Bits. Bits werden zu Bytes zusammengefasst. Alle Dateien, egal ob Bilder, Video, Text etc. sind eine Abfolge von Bits. Die Art der Speicherung macht den Unterschied der Dateien aus. So kann man theoretisch mit Air jede beliebige Datei schreiben oder lesen.
Die Klassen FileStream und URLStream implementieren eine Actionscript Schnittstelle: flash.utils.IDataInput
Diese Klasse erfordert eine Eigenschaft bytesAvailable. Das bedeutet, wieviele Bytes im Puffer sind und gelesen werden können.
Außerdem erfordert die Klasse verschiedene Methoden die Bytes zu lesen.
So stehen zum Lesen von Strings 3 Methoden zur Verfügung:
readUTF(), readUTFBytes(), readMultiByte()
Im folgenden Beispiel sollte ein dynamisches Textfeld mit Instanznamen anzeige auf der Bühne liegen. Außerdem muss eine Textdatei namens blabla.txt auf dem Desktop liegen.
import flash.filesystem.File; import flash.net.FileReference; import flash.filesystem.FileStream; import flash.filesystem.FileMode; var file:File = File.desktopDirectory.resolvePath("blabla.txt"); var fileStream:FileStream = new FileStream(); fileStream.open(file, FileMode.READ); anzeige.appendText(fileStream.readUTFBytes( fileStream.bytesAvailable)); fileStream.close();
Im folgenden Beispiel muss ein Button auf der Bühne liegen, Instanzname "but". Durch klicken auf den Button wird in eine Datei log.txt, die auf dem Desktop liegt, ein Eintrag mit dem aktuellen Datum erzeugt.
import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; function addLogEntry(evt:MouseEvent):void { var file:File = File.desktopDirectory.resolvePath("log.txt"); var stream:FileStream = new FileStream(); stream.open(file, FileMode.APPEND); stream.writeUTFBytes("Log entry" + new Date() +"\n"); stream.close(); } but.addEventListener(MouseEvent.CLICK, addLogEntry);
IDataInput Methoden zum Lesen und Schreiben von Daten
Formattyp | Format | Info | Methoden Lesen | Methoden Schreiben | Actionscript Objekt Typen |
---|---|---|---|---|---|
Raw Bytes | Byte | ein oder mehrere Raw Bytes | readByte() readBytes() redUnsignedBytes() |
writeByte() writeBytes() writeUnsignedBytes() |
int ByteArray |
Boolsche Werte | Boolean | 0 für false, ansonsten true | readBoolean() | writeBoolean() | Boolean |
Zahlen | Short | 16-Bit-Integer | readShort() readUnsignedShort() |
writeShort() writeUnsignedShort() |
int unit |
Integer | 32-Bit-Integer | readInt() readUnsignedInt() |
writeInt() writeUnsignedInt() |
int uint |
|
Float | Fließkommazahl mit einfacher Genauigkeit | readFloat() | writeFloat() | Number | |
Double | Fließkommazahl mit doppelter Genauigkeit | readDouble() | writeDouble() | Number | |
Strings | Multibyte | String aus einem bestimmten Zeichensatz | readMultiByte() | writeMultiByte() | String |
UTF-8 | String mit UTF-8-Zeichencodierung | readUTF() readUTFBytes() |
writeUTF() writeUTFBytes() |
String | |
Objekte | Object | Objekte die mit dem ActionScript Message Format (AMF) serialisiert und deserialisiert werden | readObject() | writeObject() | Jedes Objekt das mitAMF sersialisiert werden kann |
Siehe folgenden Link zum Thema Object serialisieren und deserialisieren
Wie man in der letzten Zeile der Tabelle oben sehen kann, ist es auch möglich Objekte in Dateien zu schreiben und zu lesen. Dazu muss die Klasse mit einem Alias versehen werden:
registerClassAlias("Person", Person);
Im folgenden habe ich eine Klasse Person erstellt.
In einer Air oder Fla Datei wird ein Objekt dieser Klasse erstellt und diesem ein paar Eigenschaftswerte zugewiesen. Die Variablen der Klasse müssen alle Public sein oder der Zugriff muss mit getter und setter Methoden erfolgen.
Anschließend wird das Objekt mit writeObject in ein Verzeichnis in eine Datei log.data gespeichert.
In einer anderen Fla Datei wird diese log.data eingelesen und das Objekt deserialisiert. Dort wird dann auch der Alias vergeben.
package { public class Person { public var firstName:String; public var lastName:String; public var age:uint; public var city:String; } }
import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; registerClassAlias("Person", Person); var kirk:Person = new Person(); kirk.firstName = "William"; kirk.lastName = "Shatner"; kirk.age = 80; trace(kirk.firstName); but.addEventListener(MouseEvent.CLICK, addLogEntry); function addLogEntry(evt:MouseEvent):void { var file:File = File.desktopDirectory.resolvePath("../flash/air/file1/log.data"); var stream:FileStream = new FileStream(); stream.open(file, FileMode.APPEND); stream.writeObject(kirk); stream.close(); }
import flash.filesystem.File; import flash.net.FileReference; import flash.filesystem.FileStream; import flash.filesystem.FileMode; registerClassAlias("Person", Person); var file:File = File.desktopDirectory.resolvePath("../flash/air/file1/log.data"); var fileStream:FileStream = new FileStream(); fileStream.open(file, FileMode.READ); var ws:Person = fileStream.readObject() as Person; anzeige.appendText(ws.firstName); fileStream.close();
Auch in diesem Beispiel gibt es 2 Dateien write.fla und read.fla, sowie die Klasse person.as, die ich im vorigen Beispiel aufgeführt habe.
In write.fla muss ein Button liegen mit dem Instanznamen write_btn. Dieser schreibt die beiden Instanzen der Klasse Person, welche der oben aufgeführten Klasse entspricht, in eine Datei namens person.data
In read.fla muss ein Button liegen mit Instanznamen read_btn. Außerdem muss ein dynamisches Textfeld mit Instanznamen anzeige auf der Bühne liegen. Durch Klick auf den Button wird die person.data eingelesen und die Eigenschaften der Objekte in das Textfeld geschrieben.
write.fla
import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; registerClassAlias("Person", Person); var pers1:Person = new Person(); pers1.firstName = "William"; pers1.lastName = "Shatner"; pers1.age = 80; var pers2:Person = new Person(); pers2.firstName = "Patrick"; pers2.lastName = "Steward"; pers2.age = 65; write_btn.addEventListener(MouseEvent.CLICK, addData); function addData(evt:MouseEvent):void { var file:File = File.desktopDirectory.resolvePath("../flash/air/serialize/person.data"); var stream:FileStream = new FileStream(); stream.open(file, FileMode.APPEND); stream.writeObject(new[pers1, pers2]); stream.close(); }
read.fla
import flash.filesystem.File; import flash.net.FileReference; import flash.filesystem.FileStream; import flash.filesystem.FileMode; import flash.events.MouseEvent; registerClassAlias("Person", Person); read_btn.addEventListener(MouseEvent.CLICK, getData); function getData(evt:MouseEvent):void { var file:File = File.desktopDirectory.resolvePath("../flash/air/serialize/person.data"); var fileStream:FileStream = new FileStream(); fileStream.open(file, FileMode.READ); var people:Vector.= fileStream.readObject() as Vector. ; for each (var p:Person in people) { anzeige.appendText(p.firstName + " " + p.lastName + " Alter: " + p.age+"\n"); } fileStream.close(); }
Es folgt ein einfaches Beispiel. Zuerst wird ein FileReference Objekt erstellt. Dann wird mit der browse Methode auf das Dateisystem zugegriffen. Wie man sieht kann man hier auch Filter angeben, damit nur bestimmte Dateitypen angezeigt werden. Das Auswählen der Datei wird mit dem Event.SELECT abgefangen. Dann wird die Methode load erzeugt und ein EventListener für Event.COMPLETE erzeugt.
Dann werden das Byte Array einem Loader Objekt übergeben.
loader.loadBytes(evt.target.data);
Für den Loader werden auch wiederum die bekannten Event Listener erzeugt. Siehe Loader.
import flash.net.FileReference; var loader:Loader = new Loader(); var fileRef:FileReference = new FileReference(); var imageFilter:FileFilter=new FileFilter("Images","*.jpg;*.gif;*.png"); var mcPic:MovieClip = new MovieClip(); function chooseImage(evt:MouseEvent):void { fileRef.browse([imageFilter]); fileRef.addEventListener(Event.SELECT, onFileSelected); } browse_btn.addEventListener(MouseEvent.CLICK, chooseImage); function onFileSelected(evt:Event):void { fileRef.addEventListener(Event.COMPLETE, onComplete); fileRef.load(); } function onComplete(evt:Event):void { trace("File was successfully loaded."); loader.loadBytes(evt.target.data); //loader.loadBytes(fileRef.data); loader.contentLoaderInfo.addEventListener(Event.INIT, onInit); fileRef.removeEventListener(Event.COMPLETE, onComplete); } function onInit(evt:Event):void { mcPic.addChild(loader); trace(mcPic.numChildren); mcPic.width=400; mcPic.scaleY=mcPic.scaleX; addChild(mcPic); trace(this.numChildren); }
In diesem Beispiel wurden weitere Events eingefügt, um Ladevorgänge zu überwachen. Ich verzichte mal auf weitere Erklärungen.
import flash.net.FileReference; var loader:Loader = new Loader(); var fileRef:FileReference = new FileReference(); var imageFilter:FileFilter=new FileFilter("Images","*.jpg;*.gif;*.png"); function chooseImage(evt:MouseEvent):void { fileRef.browse([imageFilter]); fileRef.addEventListener(Event.SELECT, onFileSelected); fileRef.addEventListener(Event.CANCEL, onCancel); fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError); fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError); } browse_btn.addEventListener(MouseEvent.CLICK, chooseImage); function onFileSelected(evt:Event):void { fileRef.addEventListener(ProgressEvent.PROGRESS, onProgress); fileRef.addEventListener(Event.COMPLETE, onComplete); fileRef.load(); } function onProgress(evt:ProgressEvent):void { trace("Loaded " + evt.bytesLoaded + " of " + evt.bytesTotal + " bytes."); } function onComplete(evt:Event):void { trace("File was successfully loaded."); trace(evt.target.data); loader.loadBytes(evt.target.data); loader.contentLoaderInfo.addEventListener(Event.INIT, onInit); fileRef.removeEventListener(Event.COMPLETE, onComplete); } function onInit(evt:Event):void { var mcPic:MovieClip = new MovieClip(); mcPic.addChild(loader); mcPic.width=400; mcPic.scaleY=mcPic.scaleX; addChild(mcPic); } function onCancel(evt:Event):void { trace("The browse request was canceled by the user."); } function onIOError(evt:IOErrorEvent):void { trace("There was an IO Error."); } function onSecurityError(evt:Event):void { trace("There was a security error."); }
Hier wird die Bildgröße nach Querformat oder Hochformat geändert. Zuerst wird abgefragt ob es Querformat ist und die Breite die maxmale Breite übersteigt. Dann wird die Breite auf maximale Breite geändert. Andernfalls ist es quadratisch oder Hochformat. Es wird abgefragt, wenn man die Höhe auf maximale Höhe setzten würde, ob dann die Breite die maximale Breite übersteigt. Ist das der Fall wird die Breite auf maximale Breite gesetzt. In der letzten Bedingung wird lediglich auf maximale Höhe abgefragt und darauf gesetzt.
import flash.net.FileReference; var maxWidth:uint=500; var maxHeight:uint=700; var loader:Loader = new Loader(); var fileRef:FileReference = new FileReference(); var imageFilter:FileFilter=new FileFilter("Images","*.jpg;*.gif;*.png"); var mcPic:MovieClip = new MovieClip(); addChild(mcPic); function choose(evt:MouseEvent):void { fileRef.browse([imageFilter]); fileRef.addEventListener(Event.SELECT, onFileSelected); fileRef.addEventListener(Event.CANCEL, onCancel); fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError); fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError); } browse_btn.addEventListener(MouseEvent.CLICK, choose); function onFileSelected(evt:Event):void { fileRef.addEventListener(ProgressEvent.PROGRESS, onProgress); fileRef.addEventListener(Event.COMPLETE, onComplete); fileRef.load(); } function onProgress(evt:ProgressEvent):void { trace("Loaded " + evt.bytesLoaded + " of " + evt.bytesTotal + " bytes."); } function onComplete(evt:Event):void { trace("File was successfully loaded."); trace(evt.target.data); loader.loadBytes(evt.target.data); loader.contentLoaderInfo.addEventListener(Event.INIT, onInit); fileRef.removeEventListener(Event.COMPLETE, onComplete); } function onInit(evt:Event):void { try { mcPic.removeChildAt(0); } catch (e:Error) { trace("noch keine Instanz vorhanden."); } mcPic.addChild(loader); trace("breite "+loader.width+" höhe "+loader.height); var breite:uint=loader.width; var hoehe:uint=loader.height; trace((hoehe/maxHeight)*breite); if (breite>hoehe&&breite>maxWidth) { mcPic.width=maxWidth; mcPic.scaleY=mcPic.scaleX; } else if ((hoehe/maxHeight)*breite > maxWidth) { mcPic.width=maxWidth; mcPic.scaleY=mcPic.scaleX; } else if (hoehe > maxHeight) { mcPic.height=maxHeight; mcPic.scaleX=mcPic.scaleY; trace(mcPic.width); } } function onCancel(evt:Event):void { trace("The browse request was canceled by the user."); } function onIOError(evt:IOErrorEvent):void { trace("There was an IO Error."); } function onSecurityError(evt:Event):void { trace("There was a security error."); }
Hier wird aus dem geladenen Bild ein BitmapData und Bitmap Objekt erzeugt, um beispielsweise Pixelmanipulationen vorzunehmen und es dann später abzuspeichern, siehe auch meinen Tipp Bitmap
import flash.net.FileReference; var maxSize:uint=500; var loader:Loader = new Loader(); var fileRef:FileReference = new FileReference(); var mcPic:MovieClip = new MovieClip(); var pic:Bitmap=new Bitmap(); var imageFilter:FileFilter=new FileFilter("Images","*.jpg;*.gif;*.png"); function choose(evt:MouseEvent):void { fileRef.browse([imageFilter]); fileRef.addEventListener(Event.SELECT, onFileSelected); fileRef.addEventListener(Event.CANCEL, onCancel); fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError); fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError); } browse_btn.addEventListener(MouseEvent.CLICK, choose); function onFileSelected(evt:Event):void { fileRef.addEventListener(ProgressEvent.PROGRESS, onProgress); fileRef.addEventListener(Event.COMPLETE, onComplete); fileRef.load(); } function onProgress(evt:ProgressEvent):void { trace("Loaded " + evt.bytesLoaded + " of " + evt.bytesTotal + " bytes."); } function onComplete(evt:Event):void { trace("File was successfully loaded."); trace(evt.target.data); loader.loadBytes(evt.target.data); loader.contentLoaderInfo.addEventListener(Event.INIT, onInit); fileRef.removeEventListener(Event.COMPLETE, onComplete); } function onInit(evt:Event):void { mcPic.addChild(loader); var meinBitmapData:BitmapData=new BitmapData(mcPic.width,mcPic.height,true); meinBitmapData.draw(mcPic); pic.bitmapData=meinBitmapData; if (pic.width>pic.height) { pic.width=maxSize; pic.scaleY=pic.scaleX; } else { pic.height=400; pic.scaleX=pic.scaleY; } addChild(pic); } function onCancel(evt:Event):void { trace("The browse request was canceled by the user."); } function onIOError(evt:IOErrorEvent):void { trace("There was an IO Error."); } function onSecurityError(evt:Event):void { trace("There was a security error."); }
Das Thema habe ich auch in meinem Tipp Bitmap/ BitmapData erklärt. Man benötigt dazu die AS3 Core Lib, Flashplayer 10 und AS3.
Im folgenden Beispiel befindet sich eine Instanz eines Movieclips auf der Bühne. Der Instanzname lautet symb.
import com.adobe.images.JPGEncoder; var jpgEncoder:JPGEncoder = new JPGEncoder(80); var file:FileReference = new FileReference(); var bitDat:BitmapData = new BitmapData(400, 400, false, 0xffffff); bitDat.draw(symb); speichern_btn.addEventListener(MouseEvent.CLICK, onClick); function onClick(evt:MouseEvent):void{ file.save(jpgEncoder.encode(bitDat), "image.jpg"); }
Hier kann man sich nun mehrere Bilder aussuchen. Ich habe einen Movieclip mit mehreren Frames. In jedem Frame befindet sich ein anderes Bild. Von diesem Movieclip gibt es drei Instanzen auf der Bühne: mc1, mc2, mc3
import com.adobe.images.JPGEncoder; var jpgEncoder:JPGEncoder = new JPGEncoder(80); var file:FileReference = new FileReference(); var bitDat:BitmapData = new BitmapData(500, 500, false, 0xffffff); mc1.buttonMode = true; mc1.useHandCursor = true; mc2.buttonMode = true; mc2.useHandCursor = true; mc3.buttonMode = true; mc3.useHandCursor = true; mc2.gotoAndStop(2); mc3.gotoAndStop(3); mc1.addEventListener(MouseEvent.CLICK, onClick); mc2.addEventListener(MouseEvent.CLICK, onClick); mc3.addEventListener(MouseEvent.CLICK, onClick); function onClick(evt:MouseEvent):void{ var id:uint=evt.target.currentFrame; bitDat.draw(MovieClip(evt.currentTarget)); file.save(jpgEncoder.encode(bitDat), "image_"+id+".jpg"); }
Hier wurde das vorige Beispiel etwas optimiert. In der Bibliothek befindet sich wieder ein Movieclip mit mehreren frames. In jedem frame liegt ein anderes Bild. Der Movieclip hat den Klassennamen "Pictures".
Man könnte das Beispiel noch weiter optimieren, indem man die Anzahl der Frames ausliest und indem man die Bilder in einen MC mit dynamischer Laufbewegung packt. Dazu gibt es genügend Beispiele in meinen AS2 Tipps/ programmierte Bewegung.
import com.adobe.images.JPGEncoder; var jpgEncoder:JPGEncoder = new JPGEncoder(80); var file:FileReference = new FileReference(); var bitDat:BitmapData = new BitmapData(500, 500, false, 0xffffff); var picSize:uint=85; for(var i:uint=0; i<10; i++){ var pic:Pictures = new Pictures(); pic.gotoAndStop(i+1); pic.addEventListener(MouseEvent.CLICK, onClick); pic.width=picSize; pic.scaleY=pic.scaleX; pic.y=20; pic.x=i*90; pic.buttonMode = true; pic.useHandCursor = true; addChild(pic); } function onClick(evt:MouseEvent):void{ var id:uint=evt.target.currentFrame; bitDat.draw(MovieClip(evt.currentTarget)); file.save(jpgEncoder.encode(bitDat), "image_"+id+".jpg"); }
Hier wird eins der obigen Beispiele etwas erweitert und zwar wird ein Bild geladen und wieder gespeichert.
import flash.net.FileReference; import com.adobe.images.JPGEncoder; var jpgEncoder:JPGEncoder=new JPGEncoder(100); var file:FileReference = new FileReference(); var maxSize:uint=500; var loader:Loader = new Loader(); var fileRef:FileReference = new FileReference(); var mcPic:MovieClip = new MovieClip(); var pic:Bitmap=new Bitmap(); var meinBitmapData:BitmapData; var imageFilter:FileFilter=new FileFilter("Images","*.jpg;*.gif;*.png"); var id:uint=0; function choose(evt:MouseEvent):void { fileRef.browse([imageFilter]); fileRef.addEventListener(Event.SELECT, onFileSelected); fileRef.addEventListener(Event.CANCEL, onCancel); fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError); fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError); } browse_btn.addEventListener(MouseEvent.CLICK, choose); function onFileSelected(evt:Event):void { fileRef.addEventListener(ProgressEvent.PROGRESS, onProgress); fileRef.addEventListener(Event.COMPLETE, onComplete); fileRef.load(); } function onProgress(evt:ProgressEvent):void { trace("Loaded " + evt.bytesLoaded + " of " + evt.bytesTotal + " bytes."); } function onComplete(evt:Event):void { trace("File was successfully loaded."); trace(evt.target.data); loader.loadBytes(evt.target.data); loader.contentLoaderInfo.addEventListener(Event.INIT, onInit); fileRef.removeEventListener(Event.COMPLETE, onComplete); } function onInit(evt:Event):void { mcPic.addChild(loader); meinBitmapData=new BitmapData(loader.width,loader.height,true); meinBitmapData.draw(mcPic); pic.bitmapData=meinBitmapData; if (pic.width>pic.height) { pic.width=maxSize; pic.scaleY=pic.scaleX; } else { pic.height=400; pic.scaleX=pic.scaleY; } addChild(pic); } function onCancel(evt:Event):void { trace("The browse request was canceled by the user."); } function onIOError(evt:IOErrorEvent):void { trace("There was an IO Error."); } function onSecurityError(evt:Event):void { trace("There was a security error."); } save_btn.addEventListener(MouseEvent.CLICK, bildSpeichern); function bildSpeichern(evt:MouseEvent):void { id++; file.save(jpgEncoder.encode(meinBitmapData), "PixelPastor"+id+".jpg"); }