Ein großartiges Beispiel von Thibault Imbert zeigt, wie man mit ActionScript 3 unter Nutzung der JPEG-Encoder-Klasse (von Tinic Uro) JPEG-Grafiken in Flash erzeugen kann. Auf eine .flv-Datei angewendet kann man dadurch "Schnappschüsse" aus dem laufenden Video als Grafikdatei abspeichern.

Imbert: Example

Link: Live JPEG Encoder 0.3 Sources (Thibault Imbert)
Link: More fun with image formats in AS3 (JPEG-Encoder Klasse von Tinic Uro)

Ich habe den Originalcode von Thibault Imbert etwas ausgedünnt und auf das wesentliche reduziert, damit die Vorgehensweise deutlicher zu erkennen ist. Erläuterungen gibt es weiter unten im Text. Das erstellte Beispiel gibt's hier: Beispiel anschauen. Einfach auf "Vorschaubild" klicken, dann wird ein JPEG generiert und in der rechten Hälfte angezeigt. Mit einem Klick auf "Download" wird die Datei heruntergeladen.

Flv to jpg

1. Vorgehensweise

Die grundsätzliche Vorgehensweise besteht darin, ein BitmapData-Objekt mit dem JPEG-Encoder in einen binären Datenstrom zu wandeln. Danach zeigt das Beispiel von Thibault Imbert, wie die binären Daten an eine PHP-Datei geschickt werden. Das PHP-File kann das Bild nun entweder auf dem Server abspeichern oder dem Anwender direkt als Download anbieten.

2. Das JPEG erstellen und anzeigen

Zuerst wird die JPEG-Encoder Klasse mit import encoding.JPEGEncoder importiert.

Die Loader-Klasse kann SWF-Dateien, JPG-,PNG- oder GIF-Bilder laden. Zuerst wird deshalb einer neuer Loader erstellt, in den später das JPEG zum Anschauen geladen wird. Dieser Loader wird in der rechten Bildhälfte platziert.

Actionscript:
  1. var vorschau:Loader = new Loader();
  2. vorschau.x = 480;

Mit var myJPEGData:ByteArray wird ein neues Objekt vom Typ ByteArray geschaffen. Die ByteArray-Klasse ist unter flash.utils.ByteArray zu finden. Sie dient dazu binäre Daten zu verarbeiten. Dieses Objekt wird später die JPEG-Daten enthalten.

Nun folgt die Funktion createJPEG():

Actionscript:
  1. function createJPEG ( evt:MouseEvent ):void
  2.  
  3. {
  4.  
  5.     // neues Bitmap-Objekt
  6.     var myBmd:BitmapData = new BitmapData ( myVideo.width, myVideo.height );
  7.    
  8.     // Bitmap vom Video erstellen
  9.     myBmd.draw ( myVideo );
  10.    
  11.     // neues JPEP-Objekt (Angabe in Klasmmern ist die Qualitaet)
  12.     var myEnc:JPEGEncoder = new JPEGEncoder(20);
  13.    
  14.     // neues ByteArray (binäre Daten)
  15.     myJPEGData = myEnc.encode (myBmd);
  16.    
  17.     // loadBytes() lädt binäre Daten aus einem ByteArray
  18.     vorschau.loadBytes (myJPEGData);
  19.    
  20.     // vorschau auf der Bühne platzieren
  21.     addChild (vorschau);
  22.    
  23.     // Save-Button anzeigen
  24.     buttonSave.visible = true;
  25.  
  26. }

Zuerst wird ein "Snapshot" des Videos in einem BitmapData-Objekt abgespeichert. Danach kommt der JPEG-Encoder zum Einsatz: Über den Zahlenwert in Klammern wird die Qualität bzw. die Kompression festgelegt. Anschließend wird das JPEG mit der Methode encode() in das ByteArray abgelegt.

Der zu Beginn erstellte Loader kann nun mit der Methode loadBytes den JPEG-Datenstrom einlesen. Somit wird eine Vorschau des JPEGs auf der Bühne erstellt.

3. Das JPEG-File versenden

Das Anzeigen auf der Bühne ist nun erledigt. Jetzt geht es darum, dass das File serverseitig abgespeichert bzw. ein Download gestartet wird. Hier die Funktion save zum Abspeichern/Versenden des JPGs:

Actionscript:
  1. function save(evt:MouseEvent) {
  2.    
  3.     // neue URL-Anfrage festlegen
  4.     var myRequest:URLRequest = new URLRequest ("save-to-disk.php?name=meinBild.jpg");
  5.    
  6.     // Content-type (application/octet-stream) header festlegen und hinzufügen
  7.     var header:URLRequestHeader = new URLRequestHeader ("Content-type", "application/octet-stream");
  8.     myRequest.requestHeaders.push (header);
  9.     
  10.     // über POST versenden
  11.     myRequest.method = URLRequestMethod.POST;
  12.     
  13.     // JPEG-Daten mit der URL-Anfrage verknüpfen
  14.     myRequest.data = myJPEGData;
  15.    
  16.     // URLLoader mit der URL-Anfrage verknüpfen und danach laden
  17.     myURLLoader.load (myRequest);
  18.     navigateToURL (myRequest, "_blank");
  19. }

Die save-Funktion funktioniert folgendermaßen: Zuerst wird eine URL festgelegt, die aufgerufen werden soll. In diesem Fall die PHP-Datei, die den Download des JPEGs beim User initiert (Alternativ kann man diese Zeile auch mit save-to-server.php ersetzen, um das JPEG serverseitig abzuspeichern).

Nun wird der MIME-Type festgelegt. Anschließend wird als Methode des HTTP-Protokolls zum Versenden der Daten "POST" gewählt (Die Daten werden also an den Header angehängt). Danach wird das JPEG als Daten an die Anfrage gehängt. Zuletzt wird die PHP-Seite aufgerufen.

Hinweis: Das ganze funktioniert natürlich nur auf einem Server (Ansonsten erscheint nur der Quellcode der PHP-Datei).

Download: Quelldateien als ZIP

PS: Es gibt übrigens auch eine PNG-Encoder Klasse: PNG Encoder in AS3