关于javascript:将HTML Canvas捕获为gif / jpg / png / pdf?

Capture HTML Canvas as gif/jpg/png/pdf?

是否可以捕获或打印HTML画布中显示的图像或PDF?

我想通过画布生成一个图像,并能够从该图像生成PNG。


哎呀。最初的答案是针对类似问题的。修订如下:

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

使用img中的值,可以将其写为新图像,如下所示:

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


HTML5提供了canvas.todataurl(mimetype),在opera、firefox和safari 4 beta中实现。但是,有许多安全限制(主要是为了将其他来源的内容绘制到画布上)。

所以你不需要额外的图书馆。

例如

1
2
3
4
5
6
7
8
9
10
11
 <canvas id=canvas width=200 height=200></canvas>
 
      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");
      }

理论上,这应该创建一个图像,然后导航到中间有一个绿色方块的图像,但我还没有测试过。


我想我应该把这个问题的范围扩大一点,在这个问题上加上一些有用的小道消息。

要将画布作为图像,应执行以下操作:

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

您可以使用此功能将图像写入页面:

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

其中"image/png"是一个mime类型(png是唯一必须支持的类型)。如果您想要一个受支持类型的数组,您可以沿着下面的行执行一些操作:

1
2
3
4
5
6
7
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];
    }
}

您只需要在每页上运行一次—它不应该在页面的生命周期中更改。

如果希望让用户在保存文件时下载该文件,可以执行以下操作:

1
2
3
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;

如果您将它用于不同的mime类型,请确保更改image/png的两个实例,但不要更改image/octet流。还值得一提的是,如果在呈现画布时使用任何跨域资源,则在尝试使用todataurl方法时将遇到安全错误。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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);
}


我会用"wkhtmltopdf"。它工作得很好。它使用WebKit引擎(用于Chrome、Safari等),并且非常容易使用:

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

就这样!

试试看


如果您通过服务器进行下载(通过这种方式,您可以命名/转换/后期处理等您的文件),这里有一些帮助:

-使用toDataURL发布数据

-设置邮件头

1
2
3
4
5
6
7
8
9
$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");

-创建图像

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

-将图像导出为jpeg

1
2
3
4
5
6
7
8
$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();

-或作为透明PNG

1
2
3
imagesavealpha($img, true);
imagepng($img);
die($img);


另一个有趣的解决方案是幻影。它是一个无头Webkit,可以用javascript或coffeeesccript编写脚本。

其中一个用例是屏幕捕获:您可以通过编程方式捕获Web内容,包括SVG和Canvas,和/或使用缩略图预览创建网站截图。

最好的入口点是屏幕捕获wiki页面。

以下是极钟的一个很好的例子(来自Raphaeljs):

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

是否要将页面呈现为PDF?

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


如果您使用的是jquery,这是很多人都使用的,那么您可以这样实现接受的答案:

1
2
3
4
var canvas = $("#mycanvas")[0];
var img = canvas.toDataURL("image/png");

$("#elememt-to-write-to").html('<img src="'+img+'"/>');


您可以使用jspdf将画布捕获到图像或pdf中,如下所示:

1
2
3
4
var imgData = canvas.toDataURL('image/png');              
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'PNG', 10, 10);
doc.save('sample-file.pdf');

更多信息:https://github.com/mrrio/jsfd


在某些版本的Chrome上,您可以:

百万千克1使用draw image函数ctx.drawImage(image1, 0, 0, w, h);。百万千克1百万千克1在画布上单击鼠标右键百万千克1