Pregunta Capture HTML Canvas como gif / jpg / png / pdf?


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

Me gustaría generar una imagen a través de lienzo y poder generar un png a partir de esa imagen.


606
2018-05-29 00:28


origen


Respuestas:


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 como esta:

document.write('<img src="'+img+'"/>');

632
2017-08-18 16:37



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 la extracción de contenido de otro origen en el lienzo).

Entonces no necesitas 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.


104
2018-05-29 02:48



Pensé que ampliaría el alcance de esta pregunta un poco, con algunas cositas ú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 de mime (png es el único que debe ser compatible). Si desea una matriz de tipos admitidos, puede hacer algo similar a esto:

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 hacer 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 la imagen / octet-stream. También vale la pena mencionar que si usa recursos de varios dominios para representar su lienzo, encontrará un error de seguridad cuando intente utilizar el método toDataUrl.


35
2017-07-01 14:52



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

27
2018-05-22 09:40



Yo usaría "wkhtmltopdf"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!

Intentalo


21
2018-02-02 02:33



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

-Postar datos usando toDataURL

-Set los encabezados

$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
2017-07-22 17:33



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

Uno de los casos de uso es la captura de pantalla: puede capturar mediante programación los 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 el la captura de pantalla página wiki.

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

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

¿Quieres renderizar una página en un PDF?

> phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf

8
2018-05-21 11:28



Si está utilizando jQuery, que mucha gente lo hace, 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
2017-09-07 11:01