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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 14:52:17  来源:igfitidea点击:

capturing html5 canvas output as video or swf or png sequence?

javascriptjqueryhtmlvideocanvas

提问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:

我会建议:

  1. 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 );
    
  2. Send all these PNG DataURLs to your server. It'll be a very large pile of data.

  3. 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

  4. Using whatever server-side language you like, convert the base64 data to binary and write out temporary files.

  5. Using whatever 3rd party library you like on the server, convert the sequence of PNG files to a video.

  1. 用于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 );
    
  2. 将所有这些 PNG DataURL 发送到您的服务器。这将是一大堆数据。

  3. 使用您喜欢的任何服务器端语言(PHP、Ruby、Python)从数据 URL 中去除标头,这样您就只剩下 base64 编码的 PNG

  4. 使用您喜欢的任何服务器端语言,将 base64 数据转换为二进制并写出临时文件。

  5. 在服务器上使用您喜欢的任何 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 an HTMLImageElementor an HTMLVideoElementwhose 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 a SECURITY_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 a SECURITY_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 来完成此操作。这将创建一系列可以转换为视频流的图像。

http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#pixel-manipulation

http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#pixel-manipulation