Captura de lienzo HTML como gif / jpg / png / pdf?


¿Es posible capturar o imprimir lo que se muestra en un lienzo html como una imagen o pdf?

Me gustaría generar una imagen a través de canvas, y ser capaz de generar un png a partir de esa imagen.

Author: ZJR, 2009-05-29

10 answers

Oops. La respuesta original fue específica a una pregunta similar. Esto ha sido revisado:

var canvas = document.getElementById("mycanvas");
var img    = canvas.toDataURL("image/png");

Con el valor en IMG puedes escribirlo como una nueva imagen así:

document.write('<img src="'+img+'"/>');
 647
Author: donohoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-17 22:45:58

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 dibujar contenido de otro origen en el lienzo).

Así que no necesita una biblioteca adicional.

Por ejemplo

 <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 de ella, pero no he probado.

 106
Author: olliej,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-09 01:48:01

Pensé en ampliar un poco el alcance de esta pregunta, con algunas curiosidades útiles sobre el asunto.

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 soportado). Si desea una matriz de los tipos soportados, puede hacer algo en las siguientes líneas:

var imageMimes = ['image/png', 'image/bmp', 'image/gif', 'image/jpeg', 'image/tiff']; //Extend as necessary 
var acceptedMimes = new Array();
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 debe cambiar a través del ciclo de vida de una página.

Si desea que el usuario descargue el archivo tal como está guardado, 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 el image/octet-stream. También vale la pena mencionar que si utiliza cualquier recurso de dominio cruzado en la representación de su lienzo, se encontrará con un error de seguridad cuando intente utilizar el método toDataURL.

 35
Author: meiamsome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-01 14:52:10
function exportCanvasAsPNG(id, fileName) {

    var canvasElement = document.getElementById(id);

    var MIME_TYPE = "image/png";

    var imgURL = canvasElement.toDataURL(MIME_TYPE);

    var dlLink = document.createElement('a');
    dlLink.download = fileName;
    dlLink.href = imgURL;
    dlLink.dataset.downloadurl = [MIME_TYPE, dlLink.download, dlLink.href].join(':');

    document.body.appendChild(dlLink);
    dlLink.click();
    document.body.removeChild(dlLink);
}
 28
Author: david.barkhuizen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-04 10:45:04

Usaría " wkhtmltopdf". Simplemente funciona muy bien. Utiliza el motor webkit (utilizado en Chrome, Safari, etc.), y es muy fácil de usar:

wkhtmltopdf stackoverflow.com/questions/923885/ this_question.pdf

¡Eso es todo!

Pruébalo

 21
Author: lepe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-09 03:24:18

Aquí hay algo de ayuda si hace la descarga a través de un servidor (de esta manera puede nombrar/convertir/post-proceso/etc su archivo):

- Post data usando toDataURL

- Establecer las cabeceras

$filename = "test.jpg"; //or png
header('Content-Description: File Transfer');
if($msie = !strstr($_SERVER["HTTP_USER_AGENT"],"MSIE")==false)      
  header("Content-type: application/force-download");else       
  header("Content-type: application/octet-stream"); 
header("Content-Disposition: attachment; filename=\"$filename\"");   
header("Content-Transfer-Encoding: binary"); 
header("Expires: 0"); header("Cache-Control: must-revalidate"); 
header("Pragma: public");

-crear imagen

$data = $_POST['data'];
$img = imagecreatefromstring(base64_decode(substr($data,strpos($data,',')+1)));

- exportar imagen como JPEG

$width = imagesx($img);
$height = imagesy($img);
$output = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($output,  255, 255, 255);
imagefilledrectangle($output, 0, 0, $width, $height, $white);
imagecopy($output, $img, 0, 0, 0, 0, $width, $height);
imagejpeg($output);
exit();

O como PNG transparente

imagesavealpha($img, true);
imagepng($img);
die($img);
 13
Author: Community,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:08

Otra solución interesante es PhantomJS. Es un script WebKit sin cabeza con JavaScript o CoffeeScript.

Uno de los casos de uso es la captura de pantalla : puede capturar contenido web mediante programación, incluidos SVG y Canvas y/o Crear capturas de pantalla de sitios web con vista previa en miniatura.

El mejor punto de entrada es la página wiki de captura de pantalla .

Aquí hay un buen ejemplo para polar clock (de RaphaelJS):

>phantomjs rasterize.js http://raphaeljs.com/polar-clock.html clock.png

¿desea representar un página a un PDF ?

> phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf
 8
Author: Cybermaxs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-21 11:28:05

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+'"/>');
 3
Author: Pattle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-09 01:31:48

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');

Más información: https://github.com/MrRio/jsPDF

 1
Author: ferralucho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-13 21:27:32

En algunas versiones de Chrome, puedes:

  1. Utilice la función dibujar imagen ctx.drawImage(image1, 0, 0, w, h);
  2. Haga clic con el botón derecho en el lienzo
 -1
Author: Peter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-16 22:13:30