Una de las prestaciones más interesantes de Flash Player 10 es la posibilidad de poder guardar documentos directamente a disco sin necesidad de recurrir a ninguna tecnología de servidor tipo PHP, ASP o similar. Si combinamos esta función con la clase JPEG Encoder de las Core libraries de Action script veremos lo sencillo que es guardar una imagen bitmap en disco a partir de un clip de película de un documento de Flash.
A continuación vamos a mostrar cuales son los pasos a seguir para conseguirlo mediante un sencillo mini-tutorial de Flash CS4. NOTA: Este minitutorial asume que ya tienes conocimientos básicos de Flash.
- Crea un nuevo documento en Flash CS4 del tipo Archivo de Flash (AS 3.0)
- Antes de seguir descárgate las core libraries action script de la siguiente web de google. http://code.google.com/p/as3corelib/ Una vez descargado el fichero .zip descomprímelo en una carpeta de tu disco duro donde luego puedas localizarlo.
- Selecciona el comando de menú Edición>Preferencias, y dentro de las categorías del cuadro de diálogo que aparece haz clic en Action Script
- Haz clic en el botón Configuración de Action Script 3.0.
- Dentro del apartado “Ruta de biblioteca” haz clic en el icono rojo de “navegar hasta archivo SWC”
- Localiza el documento SWC de las core libraries que localizarás dentro de la carpeta donde descomprimiste el documento .zip en as3corelib-.92.1\lib\as3corelib.swc y haz clic en “Open” o “abrir” y luego clic en “Aceptar” hasta que vuelvas de nuevo al escenario del documento. Ya tenemos incluidas las core libraries de action script que haremos servir para codificar la imagen JPEG de nuestra aplicación.
- Ahora crea el movie clip que contendrá la imagen que vamos a exportar como JPEG, para ello, selecciona el comando de menú Insertar>Nuevo símbolo… y elige un símbolo del tipo clip de película.
- En el interior de símbolo dibuja la imagen que deseas guardar. Puedes dibujarla directamente en Flash con las herramientas de dibujo del propio programa o puedes importarla de Illustrator o Photoshop. Da igual que los gráficos sean bitmap o vectoriales, el resultado será siempre una imagen bitmap. NOTA: Es importante que la imagen se sitúe a la derecha y abajo del punto de referencia del clip de película (la señal de la cruz) ya que ese punto será el que se considere como coordenada de origen (esquina superior izquierda) para exportar la imagen JPEG.
- Vuelve al escenario principal y arrastra una instancia del símbolo que acabas de crear al escenario desde la biblioteca. Bautiza a esta instancia con el nombre de “dibujo_mc” dentro del panel de propiedades ya que será mediante este nombre como nos referiremos al clip de película desde action script.
- Siguiendo el mismo proceso, crea un símbolo de bóton, arrastra una instancia al escenario desde la biblioteca y dale el nombre de “guardar_btn”.
- Haz clic en la celda correspondiente al primer fotograma en la línea de tiempo y abre el panel de acciones. Vamos a comenzar a escribir el script.
import com.adobe.images.JPGEncoder;
Con esta instrucción cargamos la clase de codificación de las core library
A continuación creamos una variable del tipo Bitmap data que contendrá los píxeles de la imagen que queremos guardar. Los parámetros que pasamos al objeto Bitmap Data son el ancho y el alto del mapa de bits que esta ocasión coincidirán con el ancho y alto del clip de película creado.
import com.adobe.images.JPGEncoder;
var jpgOrigen:BitmapData = new BitmapData (dibujo_mc.width, dibujo_mc.height);
- Seguidamente dibujamos el contenido del clip de película dentro del objeto Bitmap data que acabamos de crear.
import com.adobe.images.JPGEncoder;
var jpgOrigen:BitmapData = new BitmapData (dibujo_mc.width, dibujo_mc.height);
jpgOrigen.draw(dibujo_mc);
- En el siguiente paso vamos a crear una variable del tipo JPGEncoder para almacenar la información de mapa de bits en formato JPEG. El parámetro de valor numérico que hay en el interior de los paréntesis es el nivel de calidad/compresión que tendrá el JPEG resultante
import com.adobe.images.JPGEncoder;
var jpgOrigen:BitmapData = new BitmapData (dibujo_mc.width, dibujo_mc.height);
jpgOrigen.draw(dibujo_mc);
var jpgEncoder:JPGEncoder = new JPGEncoder(85);
- Ahora toca crear una nueva variable del tipo ByteArray que será la que “encapsulará” en un fichero la información JPEG codificada. El valor de esta variable es el resultado de aplicar al bitmap jpgOrigen el método encode de la clase JPEGEncoder
import com.adobe.images.JPGEncoder;
var jpgOrigen:BitmapData = new BitmapData (dibujo_mc.width, dibujo_mc.height);
jpgOrigen.draw(dibujo_mc);
var jpgEncoder:JPGEncoder = new JPGEncoder(85);
var jpgFile:ByteArray = jpgEncoder.encode(jpgOrigen);
- El siguiente paso es asignar un “listener” al botón que hemos creado para guardar la imagen cuando hagamos clic sobre él. El listener invocará a una función a la que llamaremos “guardar” que será la que realmente guardará la imagen JPEG en disco
import com.adobe.images.JPGEncoder;
var jpgOrigen:BitmapData = new BitmapData (dibujo_mc.width, dibujo_mc.height);
jpgOrigen.draw(dibujo_mc);
var jpgEncoder:JPGEncoder = new JPGEncoder(85);
var jpgFile:ByteArray = jpgEncoder.encode(jpgOrigen);
guardar_btn.addEventListener(MouseEvent.MOUSE_UP,guardar);
- Y ahora queda de finir la función que utilizará la clase “File Reference” que utilizará un cuadro de diálogo para guardar la imagen en disco.
import com.adobe.images.JPGEncoder;
var jpgOrigen:BitmapData = new BitmapData (dibujo_mc.width, dibujo_mc.height);
jpgOrigen.draw(dibujo_mc);
var jpgEncoder:JPGEncoder = new JPGEncoder(85);
var jpgFile:ByteArray = jpgEncoder.encode(jpgOrigen);
guardar_btn.addEventListener(MouseEvent.MOUSE_UP,guardar);
function guardar (event:MouseEvent){
var ficheroGuardado:FileReference = new FileReference();
ficheroGuardado.save(jpgFile,"image.jpg");
}
Lo que se ha hecho en el interior de la función es crear una variable con una instancia de la clase “File reference” . A esta instancia se le asigna el método “save” que se encarga de abrir el cuadro de diálogo de guardar, como en cualquier aplicación de escritorio. El nombre por defecto del fichero que se guardará es “imagen.jpg”, pero por supuesto se le puede cambiar en el momento de guardarlo a disco.
Y eso es todo!!. Tendremos en nuestro disco duro un flamante fichero .JPG listo para imprimir, editar o hacer lo que queramos con él en cualquiera de nuestras aplicaciones gráficas favoritas como Photoshop o Fireworks.
Ahora pensad en la cantidad de posibilidades que se abren para el creativo con esta prestación. Con Flash es posible crear innumerables efectos gráficos mediante action script que ni tan solo podemos imaginar realizar mediante los métodos tradicionales y que ahora vamos a poder reflejar y salvar en un fichero JPEG sin necesidad de acudir a ninguna tecnología de servidor. Lo que hemos visto es tan solo la punta del iceberg, el script se puede sofisticar hasta cotas mucho más refinadas. A ver lo que sois capaces de hacer, yo…estoy en ello ;-).
Andrik
Jul 16, 2009 @ 16:20:09
El archivo as3corelib-92.1 esta dañado, me lo pueden enviar a mi correo por favor.
Programador01
Jul 16, 2009 @ 19:42:12
Hola, excelente el código!! muchas gracias!!!
Una pregunta al respecto:
Me intresa que el archivo JPG generado se guarde automáticamente en el servidor web, es decir, sin diálogo de «Guardar como».
Es posible hacerlo?
Si es posible, podrían decirme cómo?
Gracias de antemano y felicidades por la web.
Saludos.
RLopez.
B-RO
May 25, 2010 @ 16:18:08
Hola disculpa y si lo que quiero esque el usuario descargue un documento en word pdf o ppt, como se haria?, seria el mismo procedimiento
uklanor
May 25, 2010 @ 21:20:55
No, este procedimiento es solamente para imágenes bitmap.
Tito
Jun 02, 2010 @ 12:41:37
Hola, y si en vez de un MovieClip en concreto se quisiera imprimir toda la pantalla como sería?
Gracias
Tito
Jun 02, 2010 @ 13:02:56
Vale ya me he respondido yo solo, este es el codigo para que al hacer clic en el boton se guarde como jpeg ll que se ve en la pantalla del flash:
import com.adobe.images.JPGEncoder;
var jpgOrigen:BitmapData = new BitmapData (stage.width, stage.height);
jpgOrigen.draw(stage);
var jpgEncoder:JPGEncoder = new JPGEncoder(85);
var jpgFile:ByteArray = jpgEncoder.encode(jpgOrigen);
guardar_btn.addEventListener(MouseEvent.MOUSE_UP,guardar);
function guardar (event:MouseEvent){
var ficheroGuardado:FileReference = new FileReference();
ficheroGuardado.save(jpgFile,»image.jpg»);
}
Tito
Jun 02, 2010 @ 13:25:14
Nada, olvidarlo, se imprimie si, pero no salen los textos dinamicos
Palo
Ago 06, 2010 @ 01:21:33
Hola, de maravilla esto,,tengo un solo problema!! Quiero guardar la imagen, pero de un frame especifico de la linea de tiempo del movieclip dibujo_mc …alguien sabe como ? PORFAVOR…intenté haciendo un boton que me llevara hacia un frame especifico del clip dibujo_mc, y luego guardar,,pero solo guarda el primer frame.. si alguien a podido hacerlo , le ruego ayuda jejej,saludos
Muy Buena Web!!!
uklanor
Ago 19, 2010 @ 15:21:59
El problema se resuelve enviando el cabezal de reproducción al fotograma del movie clip donde está la imagen que se quiere guardar mediante una orden de Action Script -del tipo gotoAndStop()- desde la propia línea de tiempo del movie clip y no desde un elemento externo (cómo el botón que mencionas). El porqué de esto no lo se, pero el caso es que funciona.
abraham
Ago 13, 2010 @ 13:23:20
HOla, gracias por el aporte, pero yo lo que quiero saber si hay la posibilidad de hacer un gravado directo en una carpeta por default, osea, evitar que nos salga el cuadro de selecion de ubicación de windows para el archivo, sino que al presionar el boton guardar de la aplicación SWf ya este almacenado en nuestro disco duro. (aplicación soft local)
uklanor
Ago 19, 2010 @ 15:26:50
La única forma de guardar información directamente a disco es a través de shared objects (una especie de cookies), pero este tipo de objeto no permite guardar información binaria. Para guardar la imagen es preciso pasar por el cuadro de diálogo, lo cual tiene su lógica por temas de seguridad.
Para acceder directamente a disco puedes probar a crear una aplicación de escritorio independiente de navegador a través de Adbe AIR.
Alex
Ago 19, 2010 @ 00:36:26
Muy Buen tutorial, estoy haciendo un editor de personajes, crei ke me serviria para guardar la iamgen resultado, pero no se guarda la imagen si es un movieclip con varios movieclips dentro 😦 y al guardar todo el stage, solo guarda la imagen del primer fotograma de cada movieclip que uso y forman el movieclip del personaje :(, alguien conoce otro metodo?, asi de facil de usar, pero que guarde lo que se esta viendo en pantalla? 🙂
uklanor
Ago 19, 2010 @ 15:28:24
El problema se resuelve enviando el cabezal de reproducción al fotograma del movie clip donde está la imagen que se quiere guardar mediante una orden de Action Script -del tipo gotoAndStop()- desde la propia línea de tiempo del movie clip y no desde un elemento externo. El porqué de esto no lo se, pero el caso es que funciona.
Alex
Ago 31, 2010 @ 19:41:11
estaba a punto de hacer lo que me comentaste, rehacer todo mi codigo para de alguna forma pasarle los parametros a la linea del tiempo de cada movieclip y me di cuenta de una cosa, si vuelvo a posicionarme en el fotograma 1 y estando en él guardo la imagen resultante, la imagen resultante si mantiene los cambios que hice :D, muchas gracias por la ayuda =D
Jose Luis
Dic 10, 2010 @ 00:19:35
Muy bueno tu posteo, pero creo los archivos de as3 ya no sirven, hay una version nueva que es la as3corelib-93 incluso las otras ya las sacaron de la pagina original, me consegui la que recomiendas pero ni asi he podido ocuparla marca errores al localizar las librerias, podrias enviarme tus librerias si no es mucha molestia por fa. te agradezco de antemano man saludos.
uklanor
Dic 11, 2010 @ 08:14:44
Con las nuevas librerías también funciona, son las que he utilizado últimamente.
Revisa bien el código, seguramente el fallo está allí o en las preferencias de Action Script 3.
Jose Luis
Dic 16, 2010 @ 23:27:16
Pues nada mas no pude, encontre un metodo para sacar la imagen y ya lo consegui la bronca es que solo graba lo que hay en la capa que tienen la instancia mencionada, si pongo stage me desborda la memoria y nada mas no pude guardar lo de todas las capas pero gracias de cualquier forma la idea principal me sirvio de mucho y si jala con las nuevas librerias saludo mi buen uklanor.
Peter Punk
Dic 30, 2010 @ 20:04:51
Buenas, como sería el mismo código pero para Action Script 2.0?? cambiaría mucho??saludos!!
uklanor
Dic 31, 2010 @ 18:33:27
Hasta donde yo se no hay código equivalente en Action Script 2.0.
jsgjavi
Mar 09, 2011 @ 16:21:30
Buenas, alguien sabe como capturar un moviclip más alto que el stage?, me captura el tamaño real del moviclip pero no me la guarda completa, alguien sabe como decirle que sea más alto?
gracias.
Edwin Yoc
Dic 13, 2011 @ 17:04:44
Hola. Excelente Tutorial.
Alguién sabe como hacerle para que se impriman los textos del tipo «entrada» o input. No he conseguido hacerlo.
Por su ayuda, muy agradecido.
uklanor
Dic 13, 2011 @ 17:29:41
Así, a bote pronto, se me ocurre que podrías programar un Script que rellenara un campo dinámico con los valores del campo en entrada y probar si de esta manera se imprime.
Kit-K@t537
Ago 22, 2012 @ 15:04:40
Para los que tienen el problema con guardar las cajas de texto o los textinput aqui les dejo el codigo:
En los valores dentro de () pueden colocar ancho y altura, quiero desir que la pongan a preferencia, funciona mejor.
import com.adobe.images.JPGEncoder;
this.addEventListener(MouseEvent.CLICK, onSave);
var fr:FileReference = new FileReference();
function onSave(evt:MouseEvent):void
{ if(evt.target.name == ‘btnImage’)
{
var bmd:BitmapData = new BitmapData(820, 1100);
bmd.draw(dibujo_mc);
var barray:ByteArray = new JPGEncoder(100).encode(bmd);
fr.save(barray, ‘Imagem-FileReference.jpg’);
}
}
stop();
Kit-K@t537
Ago 22, 2012 @ 15:06:29
El codigo postado anteriormente guarda todo lo que esta detro del mc que eligieron ok, si tienen dudas aqui estoy.
uklanor
Ago 23, 2012 @ 11:21:56
Gracias por tu aportación. Muy interesante.
Kit-K@t537
Ago 23, 2012 @ 13:25:39
Dnd, gracias a estos tutoriales gano mi dinerin XD, ahora que consigo entender el lenguage hare mi mayor esfuerzo para ayudar a otros que buscan respuestas en la net XD.
edgarklb
Dic 12, 2012 @ 20:01:06
hola como te va?
esta muy bueno tu tutorial de hecho le di una utilidad diferente
hize un diseñador avatar en CS5 solo me falta guardar la imagen del avatar creado
crees poderme a ayudar con algun codigo o tal vez algun consejo para partir de ello?
saludos..
uklanor
Dic 12, 2012 @ 22:15:51
Simplemente deberías colocar todos los elementos del avatar dentro de un clip de película y a partir de ahí seguir las instrucciones que se indican en el tutorial.
Francisco Gamez
Feb 26, 2013 @ 04:16:33
Estoy haciendo un «editor de avatar» pero me guarda solo la imagen inicial del primer fotograma y no el avatar modificado, ¿puedes detallarme mas a fondo como resolver esto? gracias.
(he leido los comentarios de los demas usuarios, pero no logro enteder comor esolver esto)
uklanor
Feb 26, 2013 @ 16:14:12
Debes hacer que el movieClip que contiene el avatar modificado tenga más de un fotograma en su línea de tiempo y entonces, antes de ejecutar la rutina de exportación envías con un «gotoAndStop()» al fotograma donde está formado el Avatar
Guardar jpg en tiempo de ejecucin en flash | Da Webmasters
Oct 13, 2013 @ 03:30:07
Beto Castillo
Abr 04, 2014 @ 16:23:13
hola excelente tutorial , a mi me funciona si me guarda todo , menos las imagenes que cargo externas ayuda porfavor
Beto Castillo
Abr 04, 2014 @ 16:25:22
estos son mi códigos con este guardo la imagen
import com.adobe.images.JPGEncoder;
import flash.display.BitmapData;
import flash.net.FileReference;
var nombre:String = «imagen1.jpg»;
import com.adobe.images.JPGEncoder;
var jpgOrigen:BitmapData = new BitmapData (stage.width, stage.height);
jpgOrigen.draw(stage);
var jpgEncoder:JPGEncoder = new JPGEncoder(85);
var jpgFile:ByteArray = jpgEncoder.encode(jpgOrigen);
guardar_btn.addEventListener(MouseEvent.MOUSE_UP,guardar);
function guardar (event:MouseEvent){
var ficheroGuardado:FileReference = new FileReference();
ficheroGuardado.save(jpgFile,»image.jpg»);
}
Beto Castillo
Abr 04, 2014 @ 16:26:27
con este código cargo la imagen externa var miContenedor:Loader = new Loader();
miContenedor.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, statusdeCarga);
miContenedor.contentLoaderInfo.addEventListener(Event.COMPLETE, imagenLista);
var llamarImagen:URLRequest=new URLRequest(«imagenPrueba.jpg»);
miContenedor.load(llamarImagen);
function statusdeCarga(e:ProgressEvent) {
}
function imagenLista(e:Event) {
addChild(miContenedor);
}
Beto Castillo
Abr 04, 2014 @ 16:27:15
otro código que de carga externa
var holder:Loader = new Loader();
holder.load(new URLRequest(«sss.jpg»));
addChild(holder);
uklanor
Abr 09, 2014 @ 16:44:40
Hola Beto.
Siento no poder ayudarte. No tengo ni idea de porque no te está guardando las imágenes enlazadas. Hace ya mucho tiempo que no utilizo Flash para programar y esta función en concreto hace años que no la reviso. Tendría que repasar todo el código y hacer pruebas para intentar averiguar que ocurre y actualmente no dispongo ni del tiempo ni del conocimiento ni de las ganas ni de la motivación para hacerlo. Sorry…