Blog
Convertir HTML en imagen con Java Script y jQuery para descargar
- Publicado por: admin
- Categoría: Blog HTML5 Java Script jQuery
Hace poco para un proyecto personal tuve la necesidad de generar imágenes a partir de código HTML para que se puedan descargar en formato PNG, si bien en un principio parecía ser una tarea bastante fácil más adelante se me complico ya que no encontraba una librería en Java Script útil que me ayudara a realizar dicha tarea. Después de un tiempo de buscar me encontré con una llamada html2canvas la cual es bastante amigable y es soportada por la mayoría de los navegadores actuales. Con un simple código pude convertir HTML en imagen para que se pueda descargar y guardar en cualquier computadora.
Estas cosas pueden ser muy útiles cuando se tienen grillas o información muy relevante en lo sitios y las personas las comparten mucho por redes sociales.
Cómo convertir etiquetas o tags HTML en imágenes para descargar y guardar usando el lenguaje Java Script
Como hemos dicho en un principio para poder generar la imagen o foto vamos a utilizar la librería html2canvas, la cual convierte código HTML en canvas. Primero para descargar la última versíon de la librería hay que ingresar al sitio oficial https://github.com/niklasvh/html2canvas/releases.
Descargamos el archivo y lo impartamos en nuestro código junto a la librería de jQuery, ya que la vamos a utilizar para simplificar algunas tareas:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script type="text/javascript" src="html2canvas.js"></script>
Después para hacer la conversión es necesario tener algunas etiquetas o tags HTML y un botón para iniciar la descarga de la imagen como se muestra a continuación:
<div id="imagen"> <p>Esto es una prueba para <strong>exportar código HTML</strong> a imagen en formato PNG. Ofrecido por ProgramacionExtrema.com<p> </div> <button id="boton-descarga">Descargar imagen</button>
Y finalmente necesitamos la lógica para convertir el HTML, para esto vamos a crear la función downloadCanvas, la cual recibe el id del div a convertir y el nombre final del archivo descargable:
function downloadCanvas(canvasId, filename) { // Obteniendo la etiqueta la cual se desea convertir en imagen var domElement = document.getElementById(canvasId); // Utilizando la función html2canvas para hacer la conversión html2canvas(domElement, { onrendered: function(domElementCanvas) { // Obteniendo el contexto del canvas ya generado var context = domElementCanvas.getContext('2d'); // Creando enlace para descargar la imagen generada var link = document.createElement('a'); link.href = domElementCanvas.toDataURL("image/png"); link.download = filename; // Chequeando para browsers más viejos if (document.createEvent) { var event = document.createEvent('MouseEvents'); // Simulando clic para descargar event.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); link.dispatchEvent(event); } else { // Simulando clic para descargar link.click(); } } }); } // Haciendo la conversión y descarga de la imagen al presionar el botón $('#boton-descarga').click(function() { downloadCanvas('imagen', 'imagen.png'); });
Luego al presionar el botón de descarga se hará la conversión automática y la imagen se descargará en su computadora, para ver el ejemplo completo y funcionado ingrese aquí.
Detalles e inconvenientes a tener en cuenta
Dos puntos a tener en cuenta:
Para el caso en el que el contenido HTML que se desea convertir a PNG tenga imágenes, estas deben estar alojadas bajo el mismo dominio, ya que en caso contrario no se podrán visualizar por temas de seguridad.
Si la imagen exportada sale borrosa o se ve mal, le recomendamos modificar el código fuente de la librería. Básicamente debe cambiar la función getBounds por la siguiente:
function getBounds(node) { if (node.getBoundingClientRect) { var clientRect = node.getBoundingClientRect(); var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth; return { top: Math.floor(clientRect.top), bottom: Math.floor(clientRect.bottom || (clientRect.top + clientRect.height)), right: Math.floor(clientRect.left + width), left: Math.floor(clientRect.left), width: width, height: node.offsetHeight == null ? clientRect.height : node.offsetHeight }; } return {}; }
De esa forma el resultado será mucho mejor.
Bueno gente, eso es todo lo que hay que saber para poder exportar HTML a imagen en muy pocos pasos y utilizando Java Script con jQuery, espero que les sirva y ante cualquier problema no duden en dejar sus comentarios.
Hola, no me funciona.
Hola Richard, si seguís los pasos de forma correcta tendría que funcionar sin problemas como se puede ver en el ejemplo http://programacionextrema.com/examples/convertir-html-imagen/index.php, en Chrome y Firefox funciona seguro.
Hola ¿por qué las imágenes grandes me salen mochas? no sale completa.
Hola buen post, si funciona, es perfecto para un requerimiento de un cliente que tenía.
Excelente aportación. Te la agradezco mucho. Soy amateur en esto de la programación y me sacó de un atolladero.
Una duda. ¿Cómo puedo hacer para usar tu función downloadCanvas() dentro de un loop y descargar automáticamente cualquier número de imágenes con un parámetro filename dinámico? ¿es posible? ¿o dónde me recomiendas investigarlo?
De antemano mil gracias!
Buenas ^_^ gracias por el gran aporte.
Pues a mí tampoco me ha funcionado u_U he quemado el ejemplo, cambiando las URL y ni caso.
Un saludo.
Buenas de nuevo ^_^
SOLUCIONADO:
La última versión html2canvas.js no funciona
html2canvas.js 1.0.0-alpha.11 Copyright (c) 2018 Niklas von Hertzen
FUNCIONA:
html2canvas 0.5.0-alpha1 Copyright (c) 2015 Niklas von Hertzen
Mil gracias de nuevo por el aporte 😀
Hola Sergio, muchas gracias por el aporte. Un saludo.
Muy buen tutorial!! me ha servido de ayuda.
Queria preguntar algo.
¿Cómo podría hacer si tengo una imagen dentro del div para descargarla junto al texto?
Gracias!
Hay alguna manera de pasar la imagen creada al back para que se pueda imprimir desde allí.
Gracias.
Hola Erick, por supuesto, tenés que enviarla en base 64 y desde el servidor la podes guardar en la base de datos o en un directorio. Un saludo.
Cómo especificar la ruta donde quiero que me guarde la imagen descargada…??
Hola Odín. Si la intención es guardarla en la pc del usuario no hace falta, cuando se descarga automáticamente el browser le da la opción al usuario para elegir la ubicación, en cambio si lo queres hacer en el servidor ya depende del lenguaje.
Hola, alguien sabe como la imagen generada guardarla en una carpeta en el servidor?
Hola Ivan, para guardarla en el servidor vas a tener que enviar el código base64 en una petición post, luego desde el servidor decodificar ese código y la guardar en un directorio, dependiendo del lenguaje puede variar un poco pero en teoría tiene que ser algo similar. Un saludo.
Hola José, muy buen post!!
Tengo una imagen que uso de fondo en el div, pero al descargar la imagen no se ve.. Tenés idea de que debería agregar? En el html se ve perfecto, pero cuando descargo la imagen aparece un fondo negro
Buenas Pablo, con esa informació sola se me hace difícil darte una solución. Si podés darme más información tal vez pueda ayudarte.
Si quiero que la imagen se guarde en otra carpeta dentro de mi proyecto y no se descargue?
Hola Stephanie. Para eso tenes que enviar la imagen en base 64 al servidor, y una vez ahí podrás guardarla en el directorio que quieras.
Hola, ¿hay un modo de aumentar el tamaño o la escala o los dpi de la imagen?
Descargué la versión html2canvas.js 1.0.0-alpha. Hice lo de la función Math.floor()
Pero aún así la mejora no es suficiente para mi proyecto.
Se me ocurre que si hay algún modo de que se genere una imagen al doble de tamaño, o cambiar la escala o los dpi por defecto, podría mejorar el resultado.
¡Muchas gracias por el post!
Hola! quizás me puedan ayudar. Agregue un imagen al div que contine el texto, pero al descargar solo me transforma a PNG el texto, la imagen no! cómo puedo exportar también una imagen? Espero puedan ayudarme. Gracias
el div que deseo convertir a imagen lo tengo con tamaño fijo (el div está oculto), en pantallas pequeñas, la parte del div que no alcanza no aparece en la imagen. Hay alguna forma de solucionarlo?
PD: Es necesario que el div tenga un tamaño fijo en pixeles