Pour ceux qui utilisent VEGAS à noter que j'ai intégré dans l'extension ASGard une classe AS2 PrintScreen qui permet de capturer facilement via la classe BitmapData le contenu d'un clip et ainsi de renvoyer un buffer de type Array contenant l'ensemble des points (pixels) de l'image capturée. Cette classe me permet ensuite d'envoyer vers un script AMFPHP l'ensemble des points de l'image et de créer et sauver une image au format jpg sur le serveur à condition d'utiliser la librairie GD PHP.

Voici un petit exemple rapide d'utilisation de cette classe :

import flash.display.BitmapData ;
 
import asgard.display.Bitmap ;
import asgard.events.PrintScreenEvent ;
import asgard.media.PrintScreen ;
 
import asgard.events.RemotingEvent ;
import asgard.net.remoting.RemotingService ;
 
import vegas.events.Delegate ;
import vegas.events.EventListener ;
 
Stage.scaleMode = "noScale" ;
 
var captureComplete:Function = function ( e:PrintScreenEvent ):Void
{
	trace( "> capture " + e.getType() + " in " + e.getTime() + " ms") ;
	snap.bitmapData = e.getBitmapData() ;
	buffer = e.getBuffer() ;
}
 
var captureProgress:Function = function ( e:PrintScreenEvent ):Void
{
	trace( "> capture " + e.getType() + " : " + e.getPercent() + " %") ;
}
 
var captureStart:Function = function ( e:PrintScreenEvent ):Void
{
	trace( "> capture " + e.getType() ) ;
	snap.bitmapData = null ;
}
 
var serviceFault:Function = function(e:RemotingEvent):Void 
{
	var type:String = e.getType() ;
	var target:RemotingService = e.getTarget() ;
	trace("> service " + e.getType() + " > " + e.getCode()) ;
	trace("    > level : " + e.getLevel()) ;
	trace("    > line  : " + e.getLine()) ;
	trace("    > methodName : " + e.getMethodName()) ;
	trace("    > description : " +  e.getDescription()) ;
}
 
var serviceFinish:Function = function (e:RemotingEvent):Void 
{
	trace("> service " +  e.getType()) ;
}
 
var serviceResult:Function = function(e:RemotingEvent):Void 
{
	var type:String = e.getType() ;
	trace("> service " + type + " : " + e.getResult() ) ;
}
 
var serviceStart:Function = function (e:RemotingEvent):Void 
{
	trace("> service " +  e.getType()) ;
 
}
 
var service:RemotingService = new RemotingService() ;
service.addEventListener( RemotingEvent.FAULT, new Delegate(this, serviceFault)  ) ;
service.addEventListener( RemotingEvent.FINISH, new Delegate(this, serviceFinish)  ) ;
service.addEventListener( RemotingEvent.RESULT, new Delegate(this, serviceResult)  ) ;
service.addEventListener( RemotingEvent.START, new Delegate(this, serviceStart)  ) ;
 
// The buffer reference to save all pixels of the bitmap capture.
var buffer:Array ;
 
var cam:Camera = Camera.get() ;
var video:Video = container.video ;
 
video.attachVideo(cam) ;
video.width = 320 ;
video.height = 240 ;
 
var snap_mc:MovieClip = this.createEmptyMovieClip("snap_mc", 1) ;
var snap:Bitmap = new Bitmap( "snapShot", snap_mc, null, null, true ) ;
snap.x = container._x + container._width + 10 ;
snap.y = container._y ;
 
var ps:PrintScreen = new PrintScreen( container ) ;
ps.addEventListener( PrintScreenEvent.FINISH , new Delegate(this, captureComplete) ) ;
ps.addEventListener( PrintScreenEvent.PROGRESS , new Delegate(this, captureProgress) ) ;
ps.addEventListener( PrintScreenEvent.START , new Delegate(this, captureStart) ) ;
 
var gatewayUrl = "http://localhost/test/php/gateway.php" ; // gateway of the AMFPHP service
 
var id:Number = 0 ;
 
// the button to capture all pixels in the buffer of the PrintScreen instance.
captureButton.onPress = function()
{
	ps.run() ;
}
 
// the button to launch the AMFPHP service and save the picture
saveButton.onPress = function()
{
 
	service.gatewayUrl = gatewayUrl ;
	service.serviceName = "SnapShot" ;
	service.methodName = "save" ;
 
	if (buffer.length > 0)
	{
		service.params = [  
			id++ ,
			ps.getBuffer(),
			ps.width , // width of the capture.
			ps.height  // height of the capture.
		] ;
		service.trigger() ;
	}
}

Comme vous pouvez le voir dans le code ci-dessus j'utilise :

  • Un objet Video ayant pour nom d'occurence "video" contenu dans un clip "container" posé sur la scène de flash.
  • 2 clips avec les noms d'occurrence : captureButton et saveButton. Ces clips servent de bouton et permettent de lancer la capture et l'enregistrement de l'image.
  • Ma classe asgard.display.Bitmap (polymorphe avec la classe AS3 flash.display.Bitmap) pour afficher rapidement le résultat de la capture.
  • Ma classe asgard.net.remoting.RemotingService pour communiquer avec AMFPhp.

J'espère pouvoir bientôt trouver le temps pour écrire des tutoriels plus détaillés sur les différentes classes de cet exemple.

Voici mon service AMFPHP qui me permet de tester l'enregistrement de l'image sur le serveur. A noter que j'utilise pour mes tests le serveur WAMP en activant l'extension GD en passant par les options du serveur : PHP Settings -> PHP Extensions -> php_gd2

geshi php
<?php

/**
 * This remoting AMFPhp service is used to save a picture in the server.
 * @author eKameleon
 */
class SnapShot
{

    /**
     * Creates a new SnapShot instance.
     */
    function SnapShot ()
    {

        $this->methodTable = array
        (
            "save" => array
            (
                "description" => "Create and save a new SnapShot on the db" ,
                "access"      => "remote"
            )
        ) ;

    }

    /**
     * Inserts a stack of all pixels to creates a picture on the server.
     * @param the id of the snapshot.
     * @param $stack the buffer of all pixels to create a picture.
     * @param $width the width of the snapshot (default value is 340).
     * @param $height the height of the snapshot (default value is 240).
     * @param $quality the quality (default value is 85%).
     * @return 'true' if the save is success.
     */
    /*public*/ function save( $id , $stack , $width=320 , $height=240 , $quality=85 )
    {
        $root = "../../" ;
        $path = "library/" ;

        if (count($stack) > 0)
        {
            $file =  'picture_' . $id . '.jpg' ;
            $output = imagecreatetruecolor( $width , $height ) ;
            $cpt = 0 ;
            
            for( $i = 0 ; $i < $height ; $i++ )
            {
                for( $j = 0 ; $j < $width ; $j++ ) 
                {
                    imagesetpixel( $output, $j, $i, $stack[$cpt] ) ;
                    $cpt++;
                }
            }
            
            imageantialias( $output, true ) ;
	
            header("Content-type:image/jpeg");

            return imagejpeg( $output, $root . $path . $file , $quality ) ;
            	
        }
        		
        return false ;
    	
    }

}

?>

Dans mon exemple j'enregistre l'image dans un répertoire /library situé à la racine de mon répertoire de test sur le serveur PHP.

La capture et l'enregistrement de l'image fonctionne bien, il est certain qu'en AS3 et le protocol AMF3 il doit être beaucoup plus simple d'enregistrer une image Bitmap, sachant qu'il est également possible d'encoder l'image au format JPG ou PNG directement en AS3 mais en AS2 avec Flash8 cette solution reste une bonne solution.

Comme d'habitude pour ceux qui découvrent VEGAS dans cet article je vous propose d'aller consulter mon tutoriel sur l'installation des sources de VEGAS via Subversion.