• inicio
  • tutoriales flash
  • trucos flash
  • faq's flash
  • enlaces flash
  • suscribirse al feed RSS

tutoriales ( todos | principiante | medio | avanzado | AS 1.0 | AS 2.0 | AS 3.0 | top )

Tutorial FLASH - Guardar como JPEG o PNG en tiempo de ejecución con ActionScript 3.0.

| | Más
Versión Flash: CS3 y superiores   |   Compatible con ActionScript 3.0   |   Nivel: Avanzado   |   Hits: 71502

En este tutorial vamos a aprender como exportar a imagen descargable en formatos JPEG o PNG una parte de nuestra película swf.

Hace tiempo publicamos un experimento que perseguía el mismo objetivo empleando ActionScript 2.0 y ASP. Sin embargo, se demostró que consumía demasiados recursos del servidor, razón por la cual abandonamos esta línea de investigación. Gracias al artículo de Clive Goodinson publicado en Adobe Developer Connection vimos que con ActionScript 3.0 la cosa cambiaba, y cambiaba para bien, ahora todo está muy optimizado y existen las clases necesarias para realizar nuestro propósito. Así que, partiendo de este recurso como referencia hemos elaborado este tutorial que esperamos os facilite las cosas. Hemos recibido muchas consultas sobre el modo de hacer esto. Sus aplicaciones son innumerables (catálogos, simuladores, e-cards,...).

Para explicar el uso de esta funcionalidad vamos a crear una supuesta pantalla de personalización de camisetas. Podremos introducir un texto y modificar algunos atributos y colores. Cuando tengamos una combinación que nos guste guardamos la imagen en el formato elegido, JPEG o PNG.

COMO HACERLO

Antes de ponernos manos a la obra, vamos a explicar de un modo claro y sencillo el mecanismo de todo ésto, después simplemente quedará comentar el código, siguiendo este orden, todo será más fácil. Aun así recordamos que este tutorial es de nivel avanzado y está destinado a usuarios que ya están familiarizados con el uso de Flash y ActionScript.

Paso 1. - Capturamos en un objeto Bitmapdata la parte u objeto de nuestra película que deseeamos guardar como imagen.

Paso 2. - Gracias a las las clases JPGEncoder y PNGEncoder (parte de la librería as3corelib de google code) convertimos los datos al tipo ByteArray, nuevo en AS 3.0. Esto nos va a permitir tener la información en un formato adecuado para trabajar con ella. Estas clases están incluidas en los zip descargables de este tutorial junto con el resto de archivos necesarios.

Llegados a este punto se plantean dos alternativas:

Paso 3. Opción A - Si publicamos para Flash Player 9 (recomendado), necesitamos aplicar una última trasformación a los datos mediante la clase Base 64 de Dynamic Flash. Con esto codificamos en una cadena en Base64 nuestro ByteArray. Esta clase también va dentro del zip. Después de codificar enviamos los datos mediante POST a una url PHP que construirá la imagen y nos mostrará el cuadro de diálogo de descarga. Veremos que este código PHP es muy sencillo.

Paso 3. Opción B - Si publicamos para Flash Player 10 (menos recomendado, se pueden perder potenciales visitantes/clientes), no es necesario aplicar la codificación en Base64 y simplemente mostramos el cuadro de diálogo de descarga gracias al nuevo método save() de la clase FileReference. Cuando Flash Player 10 esté más implantado está opción será ideal, ya que todo queda dentro de Flash y ActionScript, no son necesarios otra tecnología ni otros requisitos en el servidor.

Vamos a comentar el código de la página que emplea la opción A del paso 3.

Todo el código ActionScript va en el primer fotograma, a excepción del incluido en los archivos externos de clase. Para poder emplear las clases de los archivos externos hay que añadir el directorio src del zip a la ruta de clases del documento fla. Esto lo hacemos a través de Archivo > Configuración de publicación > Versión de ActionScript: Botón Configuración, en la parte inferior de esta ventana, donde pone "Ruta de clases:".

Ruta de Clases

// código opción A
// importamos clases necesarias

import com.adobe.images.*;
import com.dynamicflash.util.Base64;
import fl.data.DataProvider;
// contador incremental para el nombre de archivo
var img_count:uint=0;
// rellenamos los datos de los desplegables --------------
var allFonts:Array = Font.enumerateFonts(true);
allFonts.sortOn("fontName", Array.CASEINSENSITIVE);
var dp:DataProvider = new DataProvider();
var dp2:DataProvider = new DataProvider();
for(var k:uint=0;k<allFonts.length;k++){
  dp.addItem({label:allFonts[k].fontName, data:{tipo:allFonts[k].fontType, estilo:allFonts[k].fontStyle}});
}
for(var j:uint=10;j<=24;j++){
  dp2.addItem({label:j});
}
formato_cb.addItem({label:"Jpeg" , data:"JPEG"});
formato_cb.addItem({label:"Png" , data:"PNG"});
tipo_cb.dataProvider = dp;
size_cb.dataProvider = dp2;
// --------------------------------------------------------------
// objeto text format para asignar el formato al texto de la camiseta
var textFormat1:TextFormat=new TextFormat();
textFormat1.font=tipo_cb.getItemAt(0).label;
// asignamos comportamientos a: -------------------------
// botones color camiseta

blanco_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColor(1)});
azul_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColor(2)});
rojo_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColor(3)});
amarillo_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColor(4)});
verde_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColor(5)});
purpura_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColor(6)});
// botones color texto
negro2_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColorTexto(0x000000)});
blanco2_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColorTexto(0xFFFFFF)});
azul2_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColorTexto(0x0072F4)});
rojo2_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColorTexto(0xea0000)});
amarillo2_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColorTexto(0xeded00)});
verde2_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColorTexto(0x00ee00)});
purpura2_btn.addEventListener(MouseEvent.CLICK, function(){cambiarColorTexto(0xe000e0)});
// caja texto
input_txt.addEventListener(Event.CHANGE, updateTexto);
// fuente
tipo_cb.addEventListener(Event.CHANGE, updateTexto);
// cuerpo
size_cb.addEventListener(Event.CHANGE, updateTexto);
// botón guardar
guardar_mc.addEventListener(MouseEvent.CLICK, crearIMG);
// --------------------------------------------------------------
function cambiarColor(fotograma:uint){
  shirt_mc.gotoAndStop(fotograma);
}
function cambiarColorTexto(col:Number){
  textFormat1.color=col;
  texto_txt.setTextFormat(textFormat1);
}
function updateTexto(e){
  textFormat1.font=tipo_cb.selectedItem.label;
  textFormat1.size=size_cb.selectedItem.label;
  texto_txt.text=input_txt.text;
  texto_txt.setTextFormat(textFormat1);
}
function crearIMG(e):void {
  capturarIMG(shirt_mc, formato_cb.selectedItem.data);
}
function capturarIMG(target:DisplayObject, tipo:String):void {
  img_count++;
  // dirección de la url PHP
  var phpCreator:URLRequest = new URLRequest("crearIMG.php");
  phpCreator.method = URLRequestMethod.POST;
  // objeto que contendrá los datos a enviar
  var datosPOST:URLVariables = new URLVariables();
  // rutinas para capturar el área deseada, en nuestro caso el clip shirt_mc
  var relative:DisplayObject = target.parent;
  var rect:Rectangle =target.getBounds(relative);
  // borde en píxeles que se añade alrededor de la imagen
  var bordeImagen:uint=1;
  var bitmapData:BitmapData = new BitmapData(rect.width + bordeImagen * 2, rect.height + bordeImagen * 2);
  // capturamos la imagen
  bitmapData.draw(relative, new Matrix(1, 0, 0, 1, -rect.x + bordeImagen, -rect.y + bordeImagen));
  var byteArray:ByteArray;
  switch (tipo) {
    case "JPEG":
    // en el caso jpeg hay que instanciar un objeto pasando
    // la calidad JPEG antes de invocar el método

    datosPOST.nombreArchivo="imagen"+img_count+".jpg";
    var jpgEncoder:JPGEncoder = new JPGEncoder(100);
    byteArray = jpgEncoder.encode(bitmapData);
    break;
    case "PNG":
    default:
    datosPOST.nombreArchivo="imagen"+img_count+".png";
    byteArray = PNGEncoder.encode(bitmapData);
    break;
  }
  // codificamos en Base64
  var byteArrayAsString:String = Base64.encodeByteArray(byteArray);
  // rellenamos el objeto contenedor con los datos a enviar
  datosPOST.image = byteArrayAsString;
  datosPOST.tipo=tipo;
  phpCreator.data = datosPOST;
  // enviamos los datos
  navigateToURL(phpCreator, "_self");
}

Si os fijáis en el código, gran parte va destinada a programar la personalización de la camiseta, la función que realmente tiene la clave es capturarIMG(). Para terminar esta opción queda mostrar el código del archivo crearIMG.php que recibe los datos y nos pregunta por el destino de la descarga.

<?php
if ($_POST['tipo'] == 'PNG'){
  header('Content-Type: image/png');
} else {
  header('Content-Type: image/jpeg');
}
header("Content-Disposition: attachment; filename=".$_POST['nombreArchivo']);
echo base64_decode($_POST["image"]);
?>

En este enlace podéis descargar un archivo zip con todos los archivos necesarios para la opción A. Incluye archivo fla versión CS3.

Descargar opción A

Si os planteais usar la opción B del paso 3, el código sufre unas pequeñas modificaciones. Ya no es necesaria la clase BASE64, ni enviar los datos a ningún archivo PHP, sólo hay que crear un objeto FileReference y aplicar su método save() al objeto ByteArray. Aunque también hay que incluir la carpeta src en la ruta de clases del documento fla.

En este enlace podéis descargar un archivo zip con los archivos necesarios para la opción B. Incluye archivo fla versión CS4.

Descargar opción A

Trucos Flash relacionados
| | Más
flash 1flash 1flash 1flash 2flash 1flash 3flash 1flash 4