marzo 20, 2018

Tomar foto de cámara con Python y guardarla en servidor con PHP

Introducción

Acabo de publicar cómo tomar una foto de la cámara web con Python. La vez pasada, vimos cómo tomar una foto con Javascript y guardarla en servidor con PHP. Lo hicimos porque con Javascript (al menos en el navegador, no con NodeJS) no podemos escribir archivos.

Ahora puede que nos preguntemos ¿por qué tomar una foto con Python y guardarla luego con PHP? y bueno, la respuesta varía; pero a mí se me ocurre que puede que tengamos un servidor en internet que hable PHP, y que ahí alojemos nuestras fotos. O, pensando mal, podemos tomar una foto del usuario (ya que esto no pide permiso) y mandarla a nuestro servidor.

En fin, las respuestas sobran, y aquí yo respondo a cómo hacerlo. De todos modos, es responsabilidad de cada usuario hacer lo que se le dé la gana.

Requisitos

  • Tener instalado Python y pip. Aquí hay un tutorial que escribí hace algún tiempo.
  • Contar con un servidor para pruebas. En este post veremos cómo hacerlo en modo local. Si no tienes PHP o Apache, te recomiendo ver: cómo instalar PHP en Windows.
  • También recomiendo leer la entrada anterior, pues así tendremos las bases. Además, recuerda instalar opencv.

Python

Comencemos viendo cómo programaremos a Python. Ya vimos que con opencv podemos tomar una foto y guardarla en nuestro disco duro. El código era este:

Realizaremos algunas modificaciones sólo al momento de guardar la imagen, ya que no quedará en la pc del usuario; sino que la mandaremos.

Para mandarla y evitar que se pierda información en el camino vamos a codificarla con la vieja confiable: base64. Ya que Python y PHP traen por defecto la codificación/decodificación con este algoritmo o lo que sea, será fácil implementar esto.

Entonces:

  • Tomamos la foto
  • La codificamos en base64
  • Enviamos la cadena a PHP

Así que, aquí el código:

Como vemos, requerimos de nuevas librerías para poder hacer las peticiones. No hay necesidad de instalar otra cosa, pues ya vienen incluidas por defecto.

Utilizamos imencode para poner la imagen en un buffer, y a ese buffer lo codificamos en base64. Finalmente, hacemos la petición y mandamos la imagen.

Aquí termina el código (del lado del cliente, ¿tal vez?) de Python. Vamos con PHP.

PHP

5 líneas (y podrían utilizarse menos) bastan para guardar la imagen. Simplemente escribimos un archivo png… su contenido será lo que venga en el índice foto del arreglo $_POST.

Pero no lo hacemos nomás así, sino que primero comprobamos si existe algo en esa posición. Para el nombre de la imagen usamos uniqid. Y listo.

He aquí el grandioso código.

Por cierto, al final hacemos un json_encode y mandamos los bytes que se escribieron. Esto no lo estamos capturando en Python, pero por si quisiéramos, podríamos hacerlo. Además, en este caso lo hago para ser educado y no quedar sin responder.

Importante: este archivo, en mi caso, está en mi servidor en una carpeta llamada “fotos_python“. Recuerda que si cambias la ruta o el nombre del archivo php, también debes cambiar la variable en Python.

Probando

Un post sin probar el resultado sería un post sin sentido. Voy a probarlo ahora mismo…

Tomar foto con Python y enviar a PHP

Tomar foto con Python y enviar a PHP

Ahí dice que ya se envió. Si visito mi disco duro en donde está la carpeta pública de mi servidor, veré esto:

Imagen almacenada en servidor correctamente

Imagen almacenada en servidor correctamente

Ahí está la foto. Y digo lo mismo que la vez pasada: tengo cubierta mi cámara, pero el script sirve como un encanto. Además, ¿a qué le tomaría foto para comprobarlo?

Conclusión

Así de fácil es esto. Me parece una combinación perfecta Python y PHP. Por cierto, podríamos loguear la IP del cliente, la hora, y esas cosas… pero ya cada quien lo puede modificar a su gusto.

Así es como terminamos hoy.

Tomar foto de webcam con Python

Introducción

Ya vimos cómo tomar una foto de la cámara web o de cualquier dispositivo utilizando Javascript. En aquel post, guardábamos la foto con PHP. Hoy veremos cómo tomar una foto con Python y guardarla en el sistema.

Nota: te invito a leer cómo tomar la foto y guardarla en PHP.

Requisitos

Tener instalado Python y pip. Aquí hay un tutorial para instalar Python 3.

Instalando OpenCV

Para poder acceder a la cámara del dispositivo, necesitamos el paquete de OpenCV. Para ello, ejecutamos lo siguiente en la línea de comandos:

pip install opencv-python

Voy a ejecutarlo en mi consola:

Si en tu caso no sale esto, no hay problema. La imagen se ve así porque ya lo había instalado previamente, pero lo desinstalé para efectos de este tutorial. Con que diga Successfully installed opencv-python… te puedes dar por satisfecho.

Accediendo a cámara

Muy bien, ahora sí podemos trabajar. El código es realmente sencillo. Accedemos a la cámara 0, vemos si se pudo abrir correctamente y si es así entonces escribimos el resultado en una imagen. En caso de que no se haya abierto la cámara, lo indicamos.

Código fuente

Aclaración sobre las cámaras

En este caso, accedemos a la cámara 0. Imaginemos que todas las cámaras del dispositivo son un arreglo. Los arreglos comienzan en 0. Si queremos acceder a la segunda cámara, utilizamos 1. Para la tercera, utilizamos 2. Y así sucesivamente, dependiendo del número de cámaras que tengamos.

Ejecutando código

Mi computadora sólo tiene una cámara, así que accedo el código que ejecuto es el mismo que puse allá arriba. Lo llamo desde mi computadora:

Tomar foto con Python y cámara web | Ejecución

Tomar foto con Python y cámara web | Ejecución

Lo ejecuté en D:\desarrollo_python, así que la foto se guardó ahí. En mis documentos iré a esa ubicación:

Foto guardada con éxito

Foto guardada con éxito

Y aquí dejo la foto que tomé:

No pienses que no funciona, simplemente mi cámara está cubierta. Pero si quieres, puedes seguir el tutorial y verás que no genera ningún problema.

Tomar foto con distinto nombre

Cada que llamamos al código de arriba, se sobrescribe la foto si ya existe. Si quisiéramos que tuviera un nombre distinto, podemos generar un id único utilizando uuid. La verdad no sé cómo funciona, sólo sé que genera un id que no se repite.

Por consecuencia, el código se modificaría así:

Y al ejecutarlo múltiples veces:

Fotos con distintos nombres

Fotos con distintos nombres

Por cierto, uuid ya viene incluido, no necesitamos utilizar pip para instalarlo.

Bonus

Luego de escribir esta entrada, me dije… ¿podemos guardar la foto en un servidor? la respuesta es sí, y aquí explico cómo hacerlo al menos con PHP.

Conclusión

Qué manera más fácil de tomar una foto. También podemos tomar vídeos, múltiples fotos, etcétera. De hecho, opencv sirve para muchas cosas más allá de tomar simples fotos. Aquí dejo el enlace a la documentación oficial.

Con esto terminamos por hoy.

Obtener último ID insertado en tabla con CodeIgniter

Introducción

Es muy probable que en nuestra base de datos (MySQL en mi caso) tengamos una tabla con un campo de auto incremento o AUTO_INCREMENT.

Si trabajamos con estos campos y con CodeIgniter, puede que nos preguntemos ¿Cómo obtener el último ID que ha sido insertado en nuestra tabla? Este ID nos sirve, por ejemplo, al hacer relaciones.

Supongamos que tenemos una tabla de productos vendidos y otra de ventas. Si en los productos vendidos guardamos el ID de venta, primero necesitamos hacer la venta, luego obtener el último ID de la base de datos y, ya con esto, guardar el Id de venta en la tabla de productos vendidos.

Obtener último ID insertado

CodeIgniter, un framework de PHP, provee esto en un método muy simple. Recordemos que para usar la base de datos ya sea en nuestro modelo o controlador, primero debemos cargarla.

El código para obtener el último ID guardado es este:

Ejemplo de obtener el último ID de la base de datos

Para poner un ejemplo, aquí dejo un modelo en donde lo he estado utilizando. Básicamente guarda la información de la persona en la base de datos y devuelve el último ID insertado.

Notemos por favor que en el constructor es en donde cargamos la base de datos.

Con eso terminamos el tutorial de hoy. Recuerda que en este caso fue de la tabla personas, pero funciona igual para todas las tablas.