Una pregunta más, ¿cómo puedo guardar la imagen que obtuve en esta etiqueta en el servidor? ¿¿Alguna conjetura??
Surya
77
Pero si uso var img = canvas.toDataURL ("image / jpeg"); Estoy obteniendo el fondo como negro completo. Cómo rectificar eso
gauti
181
Oh vamos. Respondí esto en 2009. ¿Qué esperas?
Donohoe
35
@donohoe en realidad lo respondiste en agosto de 2010 :)
nick
13
Usaría mucha menos memoria para hacer algo así var img = new Image(); img.src = canvas.toDataURL(); document.body.appendChild(img);. El document.writecódigo crea la URL de datos, ellos hacen una cadena HTML, luego colocan una copia de esa cadena en el DOM, el navegador debe analizar esa cadena HTML, colocar otra copia en el elemento de imagen y luego analizarla nuevamente para activar el URL de datos en datos de imagen, luego finalmente puede mostrar la imagen. Para una imagen de tamaño de pantalla que es una gran cantidad de memoria / copia / análisis. Solo una sugerencia
gman
116
HTML5 proporciona Canvas.toDataURL (mimetype) que se implementa en Opera, Firefox y Safari 4 beta. Sin embargo, hay una serie de restricciones de seguridad (principalmente relacionadas con el dibujo de contenido de otro origen en el lienzo).
Por lo tanto, no necesita una biblioteca adicional.
p.ej
<canvas id=canvas width=200 height=200></canvas><script>
window.onload =function(){var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");
context.fillStyle ="green";
context.fillRect(50,50,100,100);// no argument defaults to image/png; image/jpeg, etc also work on some// implementations -- image/png is the only one that must be supported per spec.
window.location = canvas.toDataURL("image/png");}</script>
Teóricamente, esto debería crear y luego navegar a una imagen con un cuadrado verde en el medio, pero no lo he probado.
Donde se guardará la imagen. ¿Ubicación en mi local?
chinna_82
55
la imagen se mostrará como una imagen en su navegador. Luego puede guardarlo en el disco o lo que sea. Aquí hay un marcador rápido y sucio genérico "Canvas2PNG" que convierte el primer lienzo de la página a PNG y lo muestra en el navegador en una nueva ventana:javascript:void(window.open().location = document.getElementsByTagName("canvas")[0].toDataURL("image/png"))
Kai Carver
Si la imagen tiene un tamaño de unos MB, prepárese para bloquear su navegador (lo hice hace un tiempo en Firefox).
Jahu
1
¿Cómo podría modificarse esto para representar múltiples imágenes?
Mentalista
Los URI de datos tienen una longitud máxima, por lo que hay un límite superior en el tamaño de una imagen que puede colocar en una url de datos.
Juha Syrjälä
44
Pensé en ampliar un poco el alcance de esta pregunta, con algunos datos útiles sobre el tema.
Para obtener el lienzo como una imagen, debe hacer lo siguiente:
var canvas = document.getElementById("mycanvas");var image = canvas.toDataURL("image/png");
Puede usar esto para escribir la imagen en la página:
document.write('<img src="'+image+'"/>');
Donde "image / png" es un tipo mime (png es el único que debe ser compatible). Si desea una matriz de los tipos admitidos, puede hacer algo en este sentido:
var imageMimes =['image/png','image/bmp','image/gif','image/jpeg','image/tiff'];//Extend as necessary var acceptedMimes =newArray();for(i =0; i < imageMimes.length; i++){if(canvas.toDataURL(imageMimes[i]).search(imageMimes[i])>=0){
acceptedMimes[acceptedMimes.length]= imageMimes[i];}}
Solo necesita ejecutar esto una vez por página; nunca debería cambiar durante el ciclo de vida de una página.
Si desea que el usuario descargue el archivo a medida que se guarda, puede hacer lo siguiente:
var canvas = document.getElementById("mycanvas");var image = canvas.toDataURL("image/png").replace("image/png","image/octet-stream");//Convert image to 'octet-stream' (Just a download, really)
window.location.href = image;
Si está usando eso con diferentes tipos de mime, asegúrese de cambiar ambas instancias de image / png, pero no la imagen / octeto-stream. También vale la pena mencionar que si usa cualquier recurso de dominio cruzado para representar su lienzo, encontrará un error de seguridad cuando intente usar el método toDataUrl.
Con su solución para descargar el archivo, debo elegir el software que quiero usar, es un poco incómodo ... ¿Hay alguna forma de reemplazar el mimo como png una vez descargado?
So4ne
1
@ So4ne No lo creo, tiene que ser una secuencia de imagen / octeto para solicitar una descarga al usuario. Si se deshace de esa línea, terminará con la página redirigiendo a la imagen. Sin embargo, me encantaría saber si alguien más conoce una forma de hacerlo bien.
meiamsome
2
usando target = "_ blank" en el enlace <a> y .click () también debería funcionar para activar la descarga (probado con URL de datos FF y download = "filename" para texto / csv y texto / plano)
Ax3l
Esto es genial. ¡Gracias! Pero, ¿qué pasa si quiero guardar en el servidor y no en el local? ¿Una entrada de archivo de formulario aceptará el img src como algo que se puede cargar?
Jefe alquimista
Ups Acabo de encontrar la respuesta. Dejando la pregunta anterior en caso de que alguien más esté mirando también stackoverflow.com/questions/13198131/…
El archivo guardado permanece en formato .svg. ¿Cómo guardarlo como png?
nullpointer
Esta es una buena solución, excepto que puede no funcionar en IE. Obteniendo error "El área de datos pasada a una llamada del sistema es demasiado pequeña"
Jose Cherian
En Chrome dice "Error de red", mientras que en Firefox funciona muy bien. (En Linux)
Ecker00
20
Yo usaría " wkhtmltopdf ". Simplemente funciona muy bien. Utiliza el motor de webkit (utilizado en Chrome, Safari, etc.), y es muy fácil de usar:
También estoy en el campamento wkhtmltopdf. Lo hemos estado usando para archivar y es INCREÍBLE.
Daniel Szabo
¿Cómo usar WKHTMLtoPDF en una página que requiere información de inicio de sesión? Estoy usando Jsreport para convertir a PDF pero capturo mi contenido con HTML2Canvas, tengo problemas para enviar el Canvas como parámetro a JSreport
Otra solución interesante es PhantomJS . Es un WebKit sin cabeza programable con JavaScript o CoffeeScript.
Uno de los casos de uso es la captura de pantalla: puede capturar mediante programación contenidos web, incluidos SVG y Canvas y / o Crear capturas de pantalla del sitio web con una vista previa en miniatura.
+1: PhantomJS es un sistema simple, bien documentado y bien pensado, perfecto para este trabajo. También permite mucho más que solo agarrar un lienzo; por ejemplo, puede modificar la página o parte de ella (a través de JS) antes de agarrar, así que haga que se vea exactamente como lo desea. ¡Perfecto!
johndodo
1
PhantomJs ahora está obsoleto
Merc
3
Si está utilizando jQuery, lo que hace mucha gente, entonces implementaría la respuesta aceptada de la siguiente manera:
var canvas = $("#mycanvas")[0];var img = canvas.toDataURL("image/png");
$("#elememt-to-write-to").html('<img src="'+img+'"/>');
La solución jQuery pura (100%) es la siguiente: $('<img>').attr('src',$('#mycanvas')[0].toDataURL('image/png')).appendTo($('#element-to-write-to').empty());exactamente una línea.
Naeel Maqsudov
1
Puede usar jspdf para capturar un lienzo en una imagen o pdf como este:
var imgData = canvas.toDataURL('image/png');var doc =new jsPDF('p','mm');
doc.addImage(imgData,'PNG',10,10);
doc.save('sample-file.pdf');
Esta es la otra manera, sin cadenas, aunque realmente no sé si es más rápido o no. En lugar de toDataURL (como todas las preguntas aquí proponen). En mi caso, quiero evitar dataUrl / base64 ya que necesito un buffer o vista Array. Entonces, el otro método en HTMLCanvasElement es toBlob. (Función TypeScript):
exportfunction canvasToArrayBuffer(canvas:HTMLCanvasElement, mime: string):Promise<ArrayBuffer>{returnnewPromise((resolve, reject)=> canvas.toBlob(async(d)=>{if(d){const r =newFileReader();
r.addEventListener('loadend', e =>{const ab = r.result;if(ab){
resolve(ab as ArrayBuffer);}else{
reject(newError('Expected FileReader result'));}}); r.addEventListener('error', e =>{
reject(e)});
r.readAsArrayBuffer(d);}else{
reject(newError('Expected toBlob() to be defined'));}}, mime));}
Otra ventaja de los blobs es que puede crear ObjectUrls para representar datos como archivos, de forma similar al miembro de 'archivos' de HTMLInputFile. Más información:
Respuestas:
Ups La respuesta original era específica de una pregunta similar. Esto ha sido revisado:
con el valor en IMG puede escribirlo como una nueva imagen de esta manera:
fuente
var img = new Image(); img.src = canvas.toDataURL(); document.body.appendChild(img);
. Eldocument.write
código crea la URL de datos, ellos hacen una cadena HTML, luego colocan una copia de esa cadena en el DOM, el navegador debe analizar esa cadena HTML, colocar otra copia en el elemento de imagen y luego analizarla nuevamente para activar el URL de datos en datos de imagen, luego finalmente puede mostrar la imagen. Para una imagen de tamaño de pantalla que es una gran cantidad de memoria / copia / análisis. Solo una sugerenciaHTML5 proporciona Canvas.toDataURL (mimetype) que se implementa en Opera, Firefox y Safari 4 beta. Sin embargo, hay una serie de restricciones de seguridad (principalmente relacionadas con el dibujo de contenido de otro origen en el lienzo).
Por lo tanto, no necesita una biblioteca adicional.
p.ej
Teóricamente, esto debería crear y luego navegar a una imagen con un cuadrado verde en el medio, pero no lo he probado.
fuente
javascript:void(window.open().location = document.getElementsByTagName("canvas")[0].toDataURL("image/png"))
Pensé en ampliar un poco el alcance de esta pregunta, con algunos datos útiles sobre el tema.
Para obtener el lienzo como una imagen, debe hacer lo siguiente:
Puede usar esto para escribir la imagen en la página:
Donde "image / png" es un tipo mime (png es el único que debe ser compatible). Si desea una matriz de los tipos admitidos, puede hacer algo en este sentido:
Solo necesita ejecutar esto una vez por página; nunca debería cambiar durante el ciclo de vida de una página.
Si desea que el usuario descargue el archivo a medida que se guarda, puede hacer lo siguiente:
Si está usando eso con diferentes tipos de mime, asegúrese de cambiar ambas instancias de image / png, pero no la imagen / octeto-stream. También vale la pena mencionar que si usa cualquier recurso de dominio cruzado para representar su lienzo, encontrará un error de seguridad cuando intente usar el método toDataUrl.
fuente
fuente
Yo usaría " wkhtmltopdf ". Simplemente funciona muy bien. Utiliza el motor de webkit (utilizado en Chrome, Safari, etc.), y es muy fácil de usar:
¡Eso es!
Intentalo
fuente
Aquí hay algo de ayuda si realiza la descarga a través de un servidor (de esta manera puede nombrar / convertir / postprocesar / etc su archivo):
-Publicar datos usando
toDataURL
-Configurar los encabezados
-crear imagen
-exportar imagen como JPEG
-o como PNG transparente
fuente
Otra solución interesante es PhantomJS . Es un WebKit sin cabeza programable con JavaScript o CoffeeScript.
Uno de los casos de uso es la captura de pantalla: puede capturar mediante programación contenidos web, incluidos SVG y Canvas y / o Crear capturas de pantalla del sitio web con una vista previa en miniatura.
El mejor punto de entrada es la página wiki de captura de pantalla .
Aquí hay un buen ejemplo para el reloj polar (de RaphaelJS):
¿Quieres renderizar una página a un PDF?
fuente
Si está utilizando jQuery, lo que hace mucha gente, entonces implementaría la respuesta aceptada de la siguiente manera:
fuente
.toDataURL
es nativo de JS.$('<img>').attr('src',$('#mycanvas')[0].toDataURL('image/png')).appendTo($('#element-to-write-to').empty());
exactamente una línea.Puede usar jspdf para capturar un lienzo en una imagen o pdf como este:
Más información: https://github.com/MrRio/jsPDF
fuente
Esta es la otra manera, sin cadenas, aunque realmente no sé si es más rápido o no. En lugar de toDataURL (como todas las preguntas aquí proponen). En mi caso, quiero evitar dataUrl / base64 ya que necesito un buffer o vista Array. Entonces, el otro método en HTMLCanvasElement es
toBlob
. (Función TypeScript):Otra ventaja de los blobs es que puede crear ObjectUrls para representar datos como archivos, de forma similar al miembro de 'archivos' de HTMLInputFile. Más información:
https://developer.mozilla.org/es/docs/Web/API/HTMLCanvasElement/toBlob
fuente
En algunas versiones de Chrome, puedes:
ctx.drawImage(image1, 0, 0, w, h);
fuente