Cómo guardar una imagen PNG del lado del servidor, desde un URI de datos base64

Resuelto Andrei Oniga asked hace 54 años • 17 respuestas

Estoy usando la herramienta JavaScript "Canvas2Image" de Nihilogic para convertir dibujos de lienzo en imágenes PNG. Lo que necesito ahora es convertir esas cadenas base64 que genera esta herramienta en archivos PNG reales en el servidor, usando PHP.

En resumen, lo que estoy haciendo actualmente es generar un archivo en el lado del cliente usando Canvas2Image, luego recuperar los datos codificados en base64 y enviarlos al servidor usando AJAX:

// Generate the image file
var image = Canvas2Image.saveAsPNG(canvas, true);   

image.id = "canvasimage";
canvas.parentNode.replaceChild(image, canvas);

var url = 'hidden.php',
data = $('#canvasimage').attr('src');

$.ajax({ 
    type: "POST", 
    url: url,
    dataType: 'text',
    data: {
        base64data : data
    }
});

En este punto, "hidden.php" recibe un bloque de datos que se parece a data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABE...

A partir de este momento, estoy bastante perplejo. Por lo que he leído, creo que se supone que debo usar la función imagecreatefromstring de PHP , pero no estoy seguro de cómo crear una imagen PNG real a partir de la cadena codificada en base64 y almacenarla en mi servidor. ¡Por favor ayuda!

Andrei Oniga avatar Jan 01 '70 08:01 Andrei Oniga
Aceptado

Debe extraer los datos de la imagen base64 de esa cadena, decodificarlos y luego guardarlos en el disco, no necesita GD ya que ya es un png.

$data = 'data:image/png;base64,AAAFBfj42Pj4';

list($type, $data) = explode(';', $data);
list(, $data)      = explode(',', $data);
$data = base64_decode($data);

file_put_contents('/tmp/image.png', $data);

Y como una sola línea:

$data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data));

Un método eficaz para extraer, decodificar y comprobar errores es:

if (preg_match('/^data:image\/(\w+);base64,/', $data, $type)) {
    $data = substr($data, strpos($data, ',') + 1);
    $type = strtolower($type[1]); // jpg, png, gif

    if (!in_array($type, [ 'jpg', 'jpeg', 'gif', 'png' ])) {
        throw new \Exception('invalid image type');
    }
    $data = str_replace( ' ', '+', $data );
    $data = base64_decode($data);

    if ($data === false) {
        throw new \Exception('base64_decode failed');
    }
} else {
    throw new \Exception('did not match data URI with image data');
}

file_put_contents("img.{$type}", $data);
drew010 avatar Jul 16 '2012 19:07 drew010

Prueba esto:

file_put_contents('img.png', base64_decode($base64string));

file_put_contents documentos

Some Guy avatar Jul 16 '2012 19:07 Some Guy