Estoy trabajando en un proyecto de arte generativo en el que me gustaría permitir a los usuarios guardar las imágenes resultantes de un algoritmo. La idea general es:
- Cree una imagen en un lienzo HTML5 utilizando un algoritmo generativo
- Cuando se completa la imagen, permita a los usuarios guardar el lienzo como un archivo de imagen en el servidor
- Permita al usuario descargar la imagen o agregarla a una galería de piezas producidas utilizando el algoritmo.
Sin embargo, estoy atrapado en el segundo paso. Después de un poco de ayuda de Google, encontré esta publicación de blog , que parecía ser exactamente lo que quería:
Lo que condujo al código JavaScript:
function saveImage() {
var canvasData = canvas.toDataURL("image/png");
var ajax = new XMLHttpRequest();
ajax.open("POST", "testSave.php", false);
ajax.onreadystatechange = function() {
console.log(ajax.responseText);
}
ajax.setRequestHeader("Content-Type", "application/upload");
ajax.send("imgData=" + canvasData);
}
y PHP correspondiente (testSave.php):
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) {
$imageData = $GLOBALS['HTTP_RAW_POST_DATA'];
$filteredData = substr($imageData, strpos($imageData, ",") + 1);
$unencodedData = base64_decode($filteredData);
$fp = fopen('/path/to/file.png', 'wb');
fwrite($fp, $unencodedData);
fclose($fp);
}
?>
Pero esto no parece hacer nada en absoluto.
Más Google muestra esta publicación de blog que se basa en el tutorial anterior. No es muy diferente, pero quizás valga la pena intentarlo:
$data = $_POST['imgData'];
$file = "/path/to/file.png";
$uri = substr($data,strpos($data, ",") + 1);
file_put_contents($file, base64_decode($uri));
echo $file;
Este crea un archivo (yay) pero está dañado y no parece contener nada. También parece estar vacío (tamaño de archivo de 0).
¿Hay algo realmente obvio que estoy haciendo mal? La ruta donde estoy almacenando mi archivo es editable, por lo que no es un problema, pero parece que no está sucediendo nada y no estoy realmente seguro de cómo depurar esto.
Editar
Siguiendo el enlace de Salvidor Dali, cambié la solicitud de AJAX para que fuera:
function saveImage() {
var canvasData = canvas.toDataURL("image/png");
var xmlHttpReq = false;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
ajax.open("POST", "testSave.php", false);
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajax.onreadystatechange = function() {
console.log(ajax.responseText);
}
ajax.send("imgData=" + canvasData);
}
¡Y ahora el archivo de imagen está creado y no está vacío! Parece que el tipo de contenido es importante y que cambiarlo para x-www-form-urlencoded
permitir que se envíen los datos de la imagen.
La consola devuelve la cadena (bastante grande) de código base64 y el archivo de datos es de ~ 140 kB. Sin embargo, todavía no puedo abrirlo y parece que no está formateado como una imagen.
fuente
ajax.send(canvasData );
mientras la usa como me gustaajax.send("imgData="+canvasData);
. Por$GLOBALS["HTTP_RAW_POST_DATA"]
lo tanto , no será lo que espera, probablemente debería usar$_POST['imgData']
.$data
en el segundo código php), todo lo que me devuelve es una línea en blanco. ¿Por qué sería eso? Parece como si ser quizás los datos enviados no es correcto, pero parece que yo estoy enviando al igual que los ejemplos muestran ...DataUriUpload
componente. Está documentado aquí y viene con varios medios adicionales de validación y aplicación de seguridad.Respuestas:
Aquí hay un ejemplo de cómo lograr lo que necesita:
1) Dibuja algo (tomado del tutorial de lienzo )
2) Convertir imagen de lienzo a formato URL (base64)
3) Envíalo a tu servidor a través de Ajax
3) Guarde base64 en su servidor como una imagen (aquí está cómo hacer esto en PHP , las mismas ideas están en todos los idiomas. El lado del servidor en PHP se puede encontrar aquí ):
fuente
You send it to your server as an ajax request
¿Este método requiere la confirmación del usuario? ¿O puedo enviar silenciosamente la imagen del lienzo al servidor?Jugué con esto hace dos semanas, es muy simple. El único problema es que todos los tutoriales solo hablan sobre guardar la imagen localmente. Así es como lo hice:
1) Configuré un formulario para poder usar un método POST.
2) Cuando el usuario termina de dibujar, puede hacer clic en el botón "Guardar".
3) Cuando se hace clic en el botón, tomo los datos de la imagen y los coloco en un campo oculto. Después de eso presento el formulario.
4) Cuando se envía el formulario, tengo este pequeño script php:
fuente
Creo que debe transferir la imagen en base64 a la imagen con blob, porque cuando usa la imagen base64, se necesitan muchas líneas de registro o se enviará mucha línea al servidor. Con blob, solo es el archivo. Puede usar este código a continuación:
Y el código del lienzo aquí:
Después de eso, puedes usar ajax con Form:
Este código utiliza la sintaxis de CoffeeScript.
si desea usar javascript, pegue el código en http://js2.coffee
fuente
Enviar imagen de lienzo a PHP:
Aquí está el script PHP:
photo_upload.php
fuente
Si desea guardar datos derivados de una
canvas.toDataURL()
función Javascript , debe convertir los espacios en blanco en más. Si no lo hace, los datos decodificados están dañados:http://php.net/manual/ro/function.base64-decode.php
fuente
He trabajado en algo similar. Tuve que convertir la imagen de Canvas codificada en Base64
Uint8Array Blob
.fuente
Además de la respuesta de Salvador Dalí:
en el lado del servidor, no olvide que los datos vienen en formato de cadena base64 . Es importante porque en algunos lenguajes de programación debes decir explícitamente que esta cadena debe considerarse como bytes no como una cadena Unicode simple.
De lo contrario, la decodificación no funcionará: la imagen se guardará pero será un archivo ilegible.
fuente