Cómo guardar una imágen en formato Base64 generada con JavaScript en el servidor con PHP

A veces, con el fin de subir una imágen al servidor en tu proyecto, tu o el usuario no podrán simplemente arrastrar o seleccionar un archivo a un file input por diferentes razónes, por ejemplo : la imágen que quieres subir es generada por medio de JavaScript a partir de un canvas o usas un canvas para que el usuario recorte el área de la foto que quiere usar manualmente.

Independientemente de la manera en la que uses u obtengas la imágen en base64, teniendo en cuenta que es una mala práctica e idea guardar una imágen como base64 o Blob en la base de datos directamente, necesitarás convertir la cadena de texto en base64 en un archivo estático (PNG o JPG) en tu servidor.

Probablemente ya sepas como enviar una imágen (texto) base64 al servidor usando una solicitud POST (con AJAX XMLHttpRequest) , sin embargo tambien mencionaremos como hacerlo, un poco de información extra no hiere a nadie y siempre trae beneficios.

Enviar base64 al servidor

Existen 2 maneras de enviar una imágen de este tipo al servidor, usando un formulario o enviandolo directamente con una llamada asíncrona.

Formulario

En la mayoria de los casos, usar un formulario puede ser util y mas viable pues puede que la imágen no sea lo unico que quieres enviar al servidor. Necesitaras usar javascript para convertir el canvas a base64 y colocar el valor retornado como valor en el textarea.

<!--- 
    Nota que debes enviar el formulario (u ajax) usando el método POST,
    pues las cadenas de texto en base64 llegan a tener una longitud que
    puede ser no permitida en el método GET
-->
<canvas id="myCanvasImage" width="500" height="500"></canvas>
<form method="POST" name="form" id="form" action="service/url/process.php">
    <textarea name="base64" id="base64"></textarea>
    <button type="submit">
        Enviar imágen
    </button>
</form>

<script>
    // En el evento submit del formulario, crear una imágen base64 usando toDataURL
    // y colocar ese valor en el textarea del formulario
    document.getElementById('form').addEventListener("submit",function(){
        var canvas = document.getElementById("myCanvasImage");
        var image = canvas.toDataURL(); // data:image/png....
        document.getElementById('base64').value = image;
    },false);
</script>

AJAX

Puedes usar jQuery AJAX para enviar facilmente la imágen en base64 como parámetro POST:

<canvas id="myCanvasImage" width="500" height="500"></canvas>

<script>
    var canvas = document.getElementById("myCanvasImage");
    var image = canvas.toDataURL(); //image/png.....

    // Usando jQuery AJAX
    $.ajax({
        url:"service/url/process.php",
        // Enviar un parámetro post con el nombre base64 y con la imagen en el
        data:{
            base64: image
        },
        // Método POST
        type:"post",
        complete:function(){
            console.log("Todo en orden");
        }
    });

    // O si usas XMLHttpRequest plano 
    //var xhr = new XMLHttpRequest();
    //xhr.open('POST', 'service/url/process.php', true);
    //xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    //xhr.onload = function () {
    //    // Hacer algo con la respuesta del servidor
    //    console.log(this.responseText);
    //};
    //
    //xhr.send('base64='+image);
</script>

Guardar imágen en base64 usando PHP

La lógica en el lado del servidor, es sumamente sencilla lo unico que debes saber es cómo obtener la imágen enviada en la solicitud (enviada en nuestro ejemplo en un parámetro POST con el nombre base64) usando $_POST (o de la manera en la que se obtiene un parámetro POST en tu framework, si usas uno).

<?php 
// Imagen base64 enviada desde javascript en el formulario
// En este caso, con PHP plano podriamos obtenerla usando :
// $baseFromJavascript = $_POST['base64'];
$baseFromJavascript = "data:image/png;base64,BBBFBfj42Pj4....";

// Nuestro base64 contiene un esquema Data URI (data:image/png;base64,)
// que necesitamos remover para poder guardar nuestra imagen
// Usa explode para dividir la cadena de texto en la , (coma)
$base_to_php = explode(',', $baseFromJavascript);
// El segundo item del array base_to_php contiene la información que necesitamos (base64 plano)
// y usar base64_decode para obtener la información binaria de la imagen
$data = base64_decode($base_to_php[1]);// BBBFBfj42Pj4....

// Proporciona una locación a la nueva imagen (con el nombre y formato especifico)
$filepath = "/path/to/my-files/image.png"; // or image.jpg

// Finalmente guarda la imágen en el directorio especificado y con la informacion dada
file_put_contents($filepath, $data);

Nota: puedes simplificar el código anterior usando una expresión regular como se muestra a continuación.

<?php 
// Imagen base64 enviada desde javascript en el formulario
// En este caso, con PHP plano podriamos obtenerla usando :
// $baseFromJavascript = $_POST['base64'];
$baseFromJavascript = "data:image/png;base64,BBBFBfj42Pj4";

// Remover la parte de la cadena de texto que no necesitamos (data:image/png;base64,)
// y usar base64_decode para obtener la información binaria de la imagen
$data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $baseFromJavascript));

$filepath = "/path/to/my-files/image.png"; // or image.jpg

// Finalmente guarda la imágen en el directorio especificado y con la informacion dada
file_put_contents($filepath,$data);

Si al guardar tu imágen base64 y esta adquiere un fondo negro, lee este articulo que te ayudará a solucionarlo y a entender porque ocurre este problema.

Que te diviertas !

Esto podría ser de tu interes

Conviertete en un programador más sociable