javascript 将 html5 画布输出捕获为视频或 swf 或 png 序列?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/4781602/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
capturing html5 canvas output as video or swf or png sequence?
提问by Bhupi
I need to take HTML5 canvas output as video or swf png sequence.
我需要将 HTML5 画布输出作为视频或 swf png 序列。
I found the following link on stackoverflow for capturing images.
Capture HTML Canvas as gif/jpg/png/pdf?
我在 stackoverflow 上找到了以下用于捕获图像的链接。
将 HTML Canvas 捕获为 gif/jpg/png/pdf?
But can anyone suggest if we want the output to be video or swf of png sequence?
但是有人可以建议我们是否希望输出是 png 序列的视频或 swf?
EDIT:
编辑:
Ok now I understood how to capture the canvas data to store on server, I tried it and it is working fine if I use only shapes, rectangle or some other graphic, but not if I draw external images on canvas element. Can anyone tell me how to capture canvas data completely whether we use graphic or external images for drawing on canvas?
好的,现在我明白了如何捕获画布数据以存储在服务器上,我尝试了它,如果我只使用形状、矩形或其他一些图形,它可以正常工作,但如果我在画布元素上绘制外部图像则不行。谁能告诉我如何完全捕获画布数据,无论我们使用图形还是外部图像在画布上绘图?
I used the following code:
我使用了以下代码:
var cnv = document.getElementById("myCanvas");
var ctx = cnv.getContext("2d");
if(ctx)
{
  var img = new Image();
  ctx.fillStyle = "rgba(255,0,0,0.5)";
  ctx.fillRect(0,0,300,300);
  ctx.fill();
  img.onload = function()
  {
     ctx.drawImage(img, 0,0);
  }
  img.src = "my external image path";
  var data = cnv.toDataURL("image/png");
}
after taking the canvas data into my "data" variable I created a new canvas and draw the captured data on that, the red rectangle drawn on the second canvas but that external image doesn't.
将画布数据放入我的“数据”变量后,我创建了一个新画布并在其上绘制捕获的数据,在第二个画布上绘制的红色矩形但外部图像没有。
Thanks in advance.
提前致谢。
回答by Phrogz
I would suggest:
我会建议:
- Use - setIntervalto capture the contents of your Canvas as a PNG data URL.- function PNGSequence( canvas ){ this.canvas = canvas; this.sequence = []; }; PNGSequence.prototype.capture = function( fps ){ var cap = this; this.sequence.length=0; this.timer = setInterval(function(){ cap.sequence.push( cap.canvas.toDataURL() ); },1000/fps); }; PNGSequence.prototype.stop = function(){ if (this.timer) clearInterval(this.timer); delete this.timer; return this.sequence; }; var myCanvas = document.getElementById('my-canvas-id'); var recorder = new PNGSequence( myCanvas ); recorder.capture(15); // Record 5 seconds setTimeout(function(){ var thePNGDataURLs = recorder.stop(); }, 5000 );
- Send all these PNG DataURLs to your server. It'll be a very large pile of data. 
- Using whatever server-side language you like (PHP, Ruby, Python) strip the headers from the data URLs so that you are left with just the base64 encoded PNGs 
- Using whatever server-side language you like, convert the base64 data to binary and write out temporary files. 
- Using whatever 3rd party library you like on the server, convert the sequence of PNG files to a video. 
- 用于 - setInterval将 Canvas 的内容捕获为 PNG 数据 URL。- function PNGSequence( canvas ){ this.canvas = canvas; this.sequence = []; }; PNGSequence.prototype.capture = function( fps ){ var cap = this; this.sequence.length=0; this.timer = setInterval(function(){ cap.sequence.push( cap.canvas.toDataURL() ); },1000/fps); }; PNGSequence.prototype.stop = function(){ if (this.timer) clearInterval(this.timer); delete this.timer; return this.sequence; }; var myCanvas = document.getElementById('my-canvas-id'); var recorder = new PNGSequence( myCanvas ); recorder.capture(15); // Record 5 seconds setTimeout(function(){ var thePNGDataURLs = recorder.stop(); }, 5000 );
- 将所有这些 PNG DataURL 发送到您的服务器。这将是一大堆数据。 
- 使用您喜欢的任何服务器端语言(PHP、Ruby、Python)从数据 URL 中去除标头,这样您就只剩下 base64 编码的 PNG 
- 使用您喜欢的任何服务器端语言,将 base64 数据转换为二进制并写出临时文件。 
- 在服务器上使用您喜欢的任何 3rd 方库,将 PNG 文件序列转换为视频。 
Edit: Regarding your comment of external images, you cannot create a data URL from a canvas that is not origin-clean. As soon as you use drawImage()with an external image, your canvas is tainted. From that link:
编辑:关于您对外部图像的评论,您不能从不是origin-clean的画布创建数据 URL 。一旦您使用drawImage()外部图像,您的画布就会受到污染。从该链接:
All canvas elements must start with their origin-cleanset to true. The flag must be set to false if any of the following actions occur:
[...]
The element's 2D context's
drawImage()method is called with anHTMLImageElementor anHTMLVideoElementwhose origin is not the same as that of the Document object that owns the canvas element.[...]
Whenever the
toDataURL()method of a canvas element whose origin-clean flag is set to false is called, the method must raise aSECURITY_ERRexception.Whenever the
getImageData()method of the 2D context of a canvas element whose origin-clean flag is set to false is called with otherwise correct arguments, the method must raise aSECURITY_ERRexception.
所有画布元素必须以它们的origin-clean设置为 true 开始。如果发生以下任何操作,则必须将该标志设置为 false:
[...]
元素的 2D 上下文的
drawImage()方法是用 anHTMLImageElement或 an调用的,HTMLVideoElement其来源与拥有画布元素的 Document 对象的来源不同。[...]
每当
toDataURL()调用其 origin-clean 标志设置为 false 的画布元素的方法时,该方法必须引发SECURITY_ERR异常。每当
getImageData()使用其他正确的参数调用其 origin-clean 标志设置为 false 的画布元素的 2D 上下文的方法时,该方法必须引发SECURITY_ERR异常。
回答by Sparafusile
To start out, you want to capture the pixel data from the canvas on a regular interval (using JavaScript timers probably). You can do this by calling context.getImageData on the canvas's context. That will create a series of images that you can turn into a video stream.
首先,您希望定期从画布中捕获像素数据(可能使用 JavaScript 计时器)。您可以通过在画布的上下文中调用 context.getImageData 来完成此操作。这将创建一系列可以转换为视频流的图像。

