Fotomatón, o haciendo fotos instantáneas online

La idea es sencilla, conectas con la webcam de tus usuarios, les haces una foto y la envías a una galería donde se pueden ver los caretos de tus visitantes. La implementación es casi tan sencilla como la teoría y el resultado es increíble y original.

El sistema es el mismo que utilizaba BloggerSnap, un servicio que tuvo un increíble éxito en su lanzamiento y que parece cerrado desde abril. Hace un año estaba por encima del puesto 40.000 en Alexa, seguramente estuvo incluso más alto. Imagino que sería muy complicado mantener el coste del ancho de banda con tanta popularidad. Hace un par de años estuvimos a punto de lanzar un servicio similar y lo desestimamos ya que no veíamos la manera de monetizarlo mientras que, a poco que tuviese éxito, los gastos se dispararían.

En un escenario normal dependerías de software que el usuario tendría que instalar para que se hiciese la foto y posteriormente te la enviase, con lo cual no conseguirías el objetivo de la instantaneidad, pero existe una solución que permite hacerlo todo mediante una aplicación online: Flash, en nuestro caso Flex 😛 .

La potencia de la plataforma Flash en el tratamiento de audio y vídeo va mucho más allá de lo que pueda parecer y permite crear aplicaciones multimedia avanzadas con participación del usuario de manera bastante rápida. Si además dispones de dinero suficiente, puedes combinarlo con Flash Media Server y los límites los pondrá tu imaginación. Otro día crearemos un videochat 😉 .

La clave es el acceso a la cámara y al micrófono del equipo que permite la plataforma Flash previa autorización del usuario, obviamente. Si lo autorizas, el player conectará con tu webcam y comenzará a mostrar el vídeo de la misma y, si la aplicación lo requiere, enviarlo a otros usuarios. Lo mismo se puede hacer con el audio.

En el taller de hoy haremos una pequeña aplicación para crear una galería de fotos instantáneas en web/blog. Los usuarios que lo deseen pueden hacerse la foto con su propia webcam y ésta quedará alojada en la galería. Simple pero llamativo.

La aplicación constará de dos partes:

  • Zona de capturas: una aplicación desarrollada en Flex que permitirá a los usuarios hacerse fotos sin más necesidad que tener una webcam.
  • Galería: una sencilla página html donde se listan todas las fotos que se han hecho los usuarios.

Capturando imágenes

Aunque pueda parecer algo muy complicado veremos a continuación que la facilidad de conectar con la webcam en Flex es impresionante.

Nuestra aplicación consta de dos únicos componentes, una imagen y un botón. La imagen nos aportará simplemente algo de estilo y el botón lo utilizaremos de disparador de nuestra cámara de fotos online.

Hay tres tareas bien diferenciadas:

  • Conectar con la webcam.
  • Capturar la foto.
  • Enviarla a nuestro servidor.

Conectar con la webcam

Con este sencillo código estaremos visualizando en nuestra aplicación la webcam que el usuario tenga conectada a su equipo.

private function insertWebcamVideo():void{
	var videoHolder:UIComponent = new UIComponent();
	if(Camera.names.length>0){
	   camera = Camera.getCamera();
	   if(camera==null || camera.width==-1 || camera.height==-1 || camera.fps==-1){
	   		Alert.show("Lo sentimos, no tienes cámara", "Error", 4, null, null, iconoAlerta);
	   		captura.enabled=false;
	   		camera=null;
	   }else{
		   camera.addEventListener(StatusEvent.STATUS, cerrar);
		   video = new Video(camera.width, camera.height);
		   video.attachCamera(camera);
		   videoHolder.addChild(video);
		   videoHolder.width=video.width;
		   videoHolder.height=video.height;
		   videoHolder.visible=true;
		   videoHolder.y=0;
		   caja.addChildAt(videoHolder, 0);
		   caja.removeChild(fotillo);
	   }
	}else{
   		Alert.show("Lo sentimos, no tienes cámara", "Error", 4, null, null, iconoAlerta);
   		captura.enabled=false;
	}
	//Security.showSettings(SecurityPanel.CAMERA);
}

Tan fácil como comprobar primero si tiene webcam (sino, obviamente, no puede hacerse fotos 😛 ) y posteriormente añadirla a un componente de vídeo que habremos incorporado a un UIComponent para mostrarlo en la aplicación. En este momento ya tenemos la cámara del usuario en vivo en la aplicación.

Capturar la foto

Teniendo el flujo de vídeo en la aplicación, queremos que cuando el usuario presione el botón “Capturar” se le haga la foto.

private function getSnapshot():void{
	var snapshot:BitmapData = new BitmapData(video.width, video.height, true);
	var m : Matrix = new Matrix();
	snapshot.draw(video, m);
	var jpegEnc:JPGEncoder=new JPGEncoder(75);
	var jpegDat:ByteArray = jpegEnc.encode(snapshot);
	var img_src:String = base64Encode(jpegDat);

	if(img_src.length>1600){
		//imagen correctamente capturada
	}else{
		Alert.show("La imagen capturada parece estar vacía", "Error", 4, null, null, iconoAlerta);
	}
}

Con este otro código conseguimos este efecto. Se obtiene una captura bit a bit del objeto de vídeo y se comprime en JPEG para enviarla al servidor. ¡Ya tenemos la foto hecha!

Enviar la foto

Utilizaremos un HTTPService para enviar por POST la foto que hemos realizado y que guardaremos en una base de datos. Añadimos a la función anterior el código para enviar la foto.

private function getSnapshot():void{
	var snapshot:BitmapData = new BitmapData(video.width, video.height, true);
	var m : Matrix = new Matrix();
	snapshot.draw(video, m);
	var jpegEnc:JPGEncoder=new JPGEncoder(75);
	var jpegDat:ByteArray = jpegEnc.encode(snapshot);
	var img_src:String = base64Encode(jpegDat);

	if(img_src.length>1600){
		var temp:Object=new Object();
		temp.imagen=img_src;
		httpService.send(temp);
		cargandoWindow = ventanaEspera(PopUpManager.createPopUp(this as DisplayObject, ventanaEspera, true));
	}else{
		Alert.show("La imagen capturada parece estar vacía", "Error", 4, null, null, iconoAlerta);
	}
}

<mx:httpservice id="httpService" showbusycursor="false" useproxy="false" method="POST" resultformat="text" url="upload.php" result="onResult()"
fault="onHTTPFault(event)" />

Ya está. El script upload.php de tu servidor recibirá por POST la variable “imagen” con el contenido de tu foto. Sólo habrá que guardarla en un archivo y habrás terminado la parta más ¿complicada? del proyecto.

if($_POST['imagen'] & strlen($_POST['imagen'])!=0 & strlen($_POST['imagen'])>1600){
        $bmd=base64_decode($_POST['imagen']);
        $im = fopen("fotos/foto.jpg",'w');
        fwrite($im,$bmd);
        fclose($im);
}

Antes de guardar la imagen en disco podrías añadir un registro a una base de datos que te permita generar después la galería. Esa parte queda a tu elección.

Generando la galería

Esta es la parte fácil, simplemente creas un script PHP (o en el lenguaje que prefieras) que liste las fotos que has ido guardando en la base de datos paginando como creas oportuno. Creo que sobran más comentarios para algo tan fácil.

Conclusiones

Hoy hemos visto cómo de una manera extremadamente rápida y sencilla se puede conectar con la webcam (y el micrófono) de los usuarios. Sólo hemos visto como hacer una fotografía instantánea de lo que se está viendo a través de la cámara, pero el sistema abre un inmenso mundo de posibilidades.

Descárgate aquí el código del proyecto.

42 comentarios en “Fotomatón, o haciendo fotos instantáneas online

  1. Hola Ignasi,

    La teoría es casi la misma, la diferencia es que para hacer fotos no necesitas nada adicional al Flash Player, él hace la foto, él la convierte a JPEG y él la envía al servidor. Para el vídeo necesitarás por detras un FMS o un Red5.

    Un Saludo

  2. Hola Andres,

    ¿Por qué no empiezas contando qué has hecho y qué no has hecho?
    ¿Te da algún error al compilar?
    ¿Has creado el script remoto para guardar la foto?

    Saludos

  3. la verdad no encuentro como hacer para ejecutar este codigo
    ya descargue el fotomaton.zip y no se que hacer con el, ya cree el proyecto en flex y copie todo dentro del proyecto y no que hago porfavor guiemen, que pena ser tan intenso 😉

  4. hola en estos momentos estos son los tres errores que me genera y te agradeceria donde me pudieras decir a que se deben

    Severity and Description Path Resource Location Creation Time Id

    1046: No se encontró el tipo o no es una constante en tiempo de compilación: JPGEncoder.

    1172: No se encontró la definición com.xplota.images.

    1180: Llamada a un método JPGEncoder posiblemente no definido.

  5. Hola Andrés,

    No he tenido ninguno de los problemas que te han surgido.
    He cogido tu código de la carpeta SRC y he creado un nuevo proyecto con él y me ha funcionado perfectamente, eso sí, una vez corregí un error que había en el mxml principal en la declaración de la aplicación, pero supongo que ese error ya lo habrás solucionado puesto que si no lo haces no compila.

  6. Hola, podrias subir tu archivo upload.php porque yo no consigo que me guarde los archivos en el servidor, y no es un tema de permisos ya que le he dado todos los permisos habidos y por haber.

  7. Hola,

    Es el que hay en el código, no hay más truco…
    1600)
    {
    $bmd=base64_decode($_POST[‘imagen’]);
    $im = fopen(“fotos/foto.jpg”,‘w’);
    fwrite($im,$bmd);
    fclose($im);
    }
    ?>
    Tendrás que tener el directorio “fotos” con permisos de escritura y ya está. Obviamente la URL del mxml que apunta al upload.php debe ser la correspondiente a tu archivo php. Si quieres puedes comprobar que el upload.php funciona creando un formulario que lo llame. Si funciona tendrá que crear el archigo “fotos/foto.jpg”.

    Osus

  8. Hola Mercu,

    Empieza por depurar el archivo de upload probando tú. Como de dije, hazte un formulario que lo llame simulando lo que hará tu aplicación a ver si guarda algo.

    Entiendo, por lo que dices, que el archivo está vacío. También puedes comprobar qué recibes en la variable $_POST[‘imagen]

  9. hoa osus espero que estes bien y te agradesco por el buen aporte ya que lo pude hacer correr a la perfeccion, solo e tenido que eliminar unas cuantas lineas pero no hay problema.

    las lineas que borre fueron del archivp upload.php
    que queda de la siguiente forma:

  10. Hola:

    He probado el ejemplo, ejecutando solo fotomaton.swf me funciona pero nose donde me guarda el archivo .. ya que tengo la carpeta //fotos/ pero no graba dentro, el proyecto en si no me funciona, no compila .. me dice que no encuentra fotomaton.html y me doy cuenta que realmente no crea el html dentro de la carpeta bin.. por favor si podes indicarme como solucionar

  11. Hola,

    El swf por su cuenta no te guardará la foto en ningún lado, tienes que ponerlo en un servidor web, sea local o remoto junto al php y el directorio de fotos, entonces verás como sí que en la carpeta “fotos” te aparecen las imágenes.

    Por otro lado, si no te crea el html, prueba a rehacer el projecto. En el Flex Builder – > Project -> Clean. Seleccionas tu proyecto y te lo reconstruirá si todo va bien. ¿Te sale la carpeta html-template en el navigator?

  12. hola osus yo de nuevo, en este momento tengo una duda, porque cuando ejecuto esta aplicación de un momento a otro el plugin de shockwave genera conflicto y cierra la ventana de navegación?????

    gracias de antemano

  13. HOLA OSUS, EL ERROR ERA DEBIDO A UN VIRUS EN LA RED DONDE LO ESTABA EJECUTANDO LA AAPLICACION DEL FOTOMATÓN PERO YA ESTA TODO BIEN, AHORA MI CONSULTA ES COMO PUEDO CAPTURAR UN STREAMING Y ALMACENAR DESDE FLEX, GRACIAS Y LO VUELVO A DECIR EL FOTOMATON ES UNA GRAN APLICACION

  14. Hola, muy bueno esta el código, he intentado mostrar la foto en una imagen ahi mismo en el flex, funciona correctamente la primera ves, solo que la segunda ves que ejecuto Captura imagen ya no me actualiza la imagen, he observado que si graba pero no actualiza a la hora de mostrar. alguien puede ayudarme por favor…???

  15. Buenas Tardes, estoy haciendo una aplicacion en php pero reuqiero capturar la imagen desde una web cam , me podria facilitar codigo por favor .Gracias

  16. Hola, muchas gracias por publicar este código, es muy útil y da a conocer alguna de las maravillas del flex. En el httpservice no veo por ningún lado el para pasar como parámetro la foto al código php, toma la foto pero no la guarda. Será ese el error?

  17. Ya he encontrado lo que pasaba, si tiene request, lo mandas como parámetro del httpservise.send(dddd)…. solo le quite la condicion al codigo PHP y me funciono perfectamente. GRACIAS

  18. Hola a Todos,

    He compilado el flex y todo perfecto tengo los permisos y la carpeta de fotos pero sigue sin guardarme el archivo.

    He seguido todos los pasos que habeis puesto y nada se queda transfieriendo datos del localhost.

    Y he probado el upload.php y es que no me recibe la variable $_POST[‘imagen’] esta vacia pero por separado por un formulario como deciais si me escribe por eso no se que puede fallar ya no se me ocurre que puede ser.

    Un saludo y gracias de antemano.

  19. hola como estan, ahora estoy trabajando en mi proyrcto de grado de la universidad y puedo hacer que en milisegundos me tome fotografias pero lo que quiero es generar un video streamming y que lo vaya almacenando en el servidor la idea es que cualquiera pueda grabar un video al estilo quick capture de youtube

  20. Hola @Osus lo probe y el archivo upload.php no funciona no se si las comillas ” este bien asi como la pusiste podrias publicar el archivo upload.php correctamente? porfavor es que llevo mas de 7 horas y nada he conseguido otros upload.php en internet pero ninguno lo logro adaptar

    dice que se creo correctamente la imagen pero veo la carpeta y no aparece nose si se tenga que tener alguna funciona de php activa o algo , en archivo en flex lo edite con la ubicacion correcta del upload.php

    una pregunta yo tengo otro codigo hecho en flash cs3 y funciona perfecto el unico problema es la imegen he visto otras paginas y en unas la imagen de la foto es mucho mejor pero en el flashq ue tengo como que se ve pizalado y mi webcam es de muy buena iagen solo que al verse en el flash sale como pixelado como soluciono eso en flash ?

  21. Hola Juan Fernando,

    El script es extremadamente sencillo, cualquiera con unos conocimientos mínimos de php podrá adaptarlo a sus necesidades. El que yo he puesto funciona, a mi por lo menos.
    Lo único raro que hace es comprobar el tamaño de la foto recibida y si es menor de 1600 bytes no la guarda, esto lo hago para no guardar fotos en blanco, pruebas que hace la gente enfocando a una pared, etc.
    Comprueba también que tienes permisos de escritura en el directorio donde dejas las fotos.

  22. Tenias razon @Osus ya lo repare gracias! una ultima cosa sabes como agrandar la imagen de la captura ? modifico y no se como hacerlo solo dime que codigo agrego ? eso es todo

    gracias espero respuesta 🙂

  23. Genial Juan Fernando.

    Para agrandar la imagen tendrás que hacerlo en la parte Flex, la idea va por aquí,
    video = new Video(camera.width, camera.height);
    Obviamente el límite está en la resolución de la cámara.

  24. Hola Osus,

    antes de nada felicitarte por la aplicación es justo lo que estaba buscando 🙂 Despes de los halagos vienen las dudas :p

    Tengo Flex Builder 3, he importado el proyecto, he hecho un clean y despues un build pero no me genera el archivo fotomaton.html por lo que no puedo ejecutar la aplicación. ¿tienes alguna idea de donde puede estar mi error?

    Un saludo.

  25. Buenas Alejandro,

    Asegúrate que en las propiedades del proyecto, sección “Flex Compiler”, tengas marcada la opción “Generate HTML wrapper file”.
    Es lo único que se me ocurre. De todos modos siempre puedes incrustar a meno el swf por tu cuenta en un html.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *