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.
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:
"""
Tomar foto con Python y opencv
@date 20-03-2018
@author parzibyte
@see https://www.parzibyte.me/blog
"""
import cv2
"""
En este caso, 0 quiere decir que queremos acceder
a la cámara 0. Si hay más cámaras, puedes ir probando
con 1, 2, 3...
"""
cap = cv2.VideoCapture(0)
leido, frame = cap.read()
if leido == True:
cv2.imwrite("foto.png", frame)
print("Foto tomada correctamente")
else:
print("Error al acceder a la cámara")
"""
Finalmente liberamos o soltamos la cámara
"""
cap.release()
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:
Así que, aquí el código:
"""
Tomar foto con Python y opencv para después mandarla
a un servidor PHP
@date 20-03-2018
@author parzibyte
@see https://www.parzibyte.me/blog
"""
import cv2
import base64 #Para codificar
#Para hablar HTTP
from urllib.parse import urlencode
from urllib.request import Request, urlopen
"""
En este caso, 0 quiere decir que queremos acceder
a la cámara 0. Si hay más cámaras, puedes ir probando
con 1, 2, 3...
"""
cap = cv2.VideoCapture(0)
leido, frame = cap.read()
if leido == True:
codificado_correctamente, buffer = cv2.imencode('.png', frame)
if codificado_correctamente:
#Nota: .decode sirve para quitar b' al inicio de la cadena
imagen_en_base64 = base64.b64encode(buffer).decode('utf-8')
url = 'http://localhost/fotos_python/foto.php' # Si cambias el servidor o ruta del archivo, cambia la url aquí
datos_enviar = {'foto': imagen_en_base64}
print("Enviando foto...")
peticion = Request(url, urlencode(datos_enviar).encode())
respuesta = urlopen(peticion).read().decode()
print("Guardada con éxito")
else:
print("Error al acceder a la cámara")
"""
Finalmente liberamos o soltamos la cámara
"""
cap.release()
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.
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.
<?php
/*
Tomar foto con Python y opencv para después mandarla
a un servidor PHP
@date 20-03-2018
@author parzibyte
@see https://www.parzibyte.me/blog
*/isset($_POST["foto"]) || exit();
$bytes = file_put_contents(uniqid() . ".png", base64_decode($_POST["foto"]));
echo json_encode($bytes);
?>
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.
Un post sin probar el resultado sería un post sin sentido. Voy a probarlo ahora mismo…
Ahí dice que ya se envió. Si visito mi disco duro en donde está la carpeta pública de mi servidor, veré esto:
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?
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.
Hoy te voy a presentar un creador de credenciales que acabo de programar y que…
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Esta web usa cookies.
Ver comentarios
Muchas gracias por el aporte, sabes que se necesita para que funcione en produccion? solo en local abre el framework pero al subir a digital no se abre, saludos!!
Puede deberse a varios factores como el certificado de seguridad, CORS, etcétera
Maravillosa entrada, muchas gracias por haber compartido espero que te encuentres bien, abrazo!