¿Es posible capturar o imprimir lo que se muestra en un lienzo html como imagen o pdf?
Me gustaría generar una imagen a través del lienzo y poder generar un png desde esa imagen.
¿Es posible capturar o imprimir lo que se muestra en un lienzo html como imagen o pdf?
Me gustaría generar una imagen a través del lienzo y poder generar un png desde esa imagen.
Respuestas:
Ups La respuesta original era específica de una pregunta similar. Esto ha sido revisado:
var canvas = document.getElementById("mycanvas");
var img = canvas.toDataURL("image/png");
con el valor en IMG puede escribirlo como una nueva imagen de esta manera:
document.write('<img src="'+img+'"/>');
var img = new Image(); img.src = canvas.toDataURL(); document.body.appendChild(img);
. El document.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 sugerencia
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.
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:
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 = 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 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.
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);
}
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:
wkhtmltopdf stackoverflow.com/questions/923885/ this_question.pdf
¡Eso es!
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
$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();
imagesavealpha($img, true);
imagepng($img);
die($img);
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):
>phantomjs rasterize.js http://raphaeljs.com/polar-clock.html clock.png
¿Quieres renderizar una página a un PDF?
> phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf
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+'"/>');
.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:
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
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):
export function canvasToArrayBuffer(canvas: HTMLCanvasElement, mime: string): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => canvas.toBlob(async (d) => {
if (d) {
const r = new FileReader();
r.addEventListener('loadend', e => {
const ab = r.result;
if (ab) {
resolve(ab as ArrayBuffer);
}
else {
reject(new Error('Expected FileReader result'));
}
}); r.addEventListener('error', e => {
reject(e)
});
r.readAsArrayBuffer(d);
}
else {
reject(new Error('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:
https://developer.mozilla.org/es/docs/Web/API/HTMLCanvasElement/toBlob