如何在使用getContext('webgl')的画布上复制另一个画布的数据?

6

我有一个用于显示医学图像的画布,还有另一个用于通过绘制形状或线条来注释图像的画布。

当我在画布#2上绘制一条线时,我希望将绘制的线复制到画布#1上,就像这样:

  var context = canvas1.getContext('2d');
  context.drawImage(canvas2,0,0);

但是因为我的canvas#1使用了getContext('webgl'),所以我做不到那样。我的意思是如何模拟。
  drawImage() for getcontext('webgl')?

非常感谢任何帮助或建议。

敬礼;

Zohreh

3个回答

1
您可以使用WebGL画布的toDataURL方法将其转换为图像,然后在2D上下文中绘制它。
ctx2D.drawImage(webGLCanvas.toDataURL("image/png"), 0, 0);

在这种情况下,我相信当初始化webgl画布时,您可能需要将preserveDrawingBuffer属性设置为true。
...getContext("webgl", {preserveDrawingBuffer: true});

谢谢您的回答,但我需要完全相反的。我想使用contex('webgl')将图像复制到画布上。 - Zohreh
抱歉我完全搞错了。情况有点复杂,在这种情况下,您需要通过 toDataURL 获取 2D 画布图像,并将其用作方形平面的纹理,然后在 openGL 上下文中绘制它,可能使用正射投影矩阵。但是我对 OpenGL 的东西不是很了解,所以无法真正帮助您 =/ - Delta
当我尝试将WebGL复制到2D时,我得到了一个空图像。 - CodeBy

1
你可以使用2D画布作为屏幕画布,在绘制任何注释之前,将WebGL画布更新并绘制到2D画布上。
drawWebGLStuff(webGLCtx);

// Copy image data of WebGL canvas to 2D canvas.
// This should be done right after WebGL rendering,
// unless preserveDrawingBuffer: true is passed during WebGL context creation,
// since WebGL will swap buffers by default, leaving no image in the drawing buffer,
// which is what we want to copy.
ctx2D.drawImage(webGLCanvas, 0, 0);

drawAnnotations(ctx2D);

(注释可以从形状列表中每帧呈现,也可以绘制到另一个屏幕外画布上,然后类似于WebGL画布将其绘制到主(屏幕)画布上。)
或者您可以通过绝对定位和z-index在页面上简单地图层画布
<div style="position: relative;">
   <canvas id="layer1" width="100" height="100" 
       style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
   <canvas id="layer2" width="100" height="100" 
       style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
</div>

这意味着复制的图像为空。 - Michael Klishevich
@MichaelKlishevich 我更新了我的答案,提到了代码顺序/preserveDrawingBuffer要求。 - 1j01

1

我在使用Emscripten时遇到了类似的问题,需要将WebGL画布复制到另一个空画布中。我使用了这段代码但是得到了空白屏幕。

var sourceCanvasWebGL = document.getElementById( "canvas" );
var destinationCanvas = document.getElementById( "canvasCopy" );
var destinationCanvasContext = destinationCanvas.getContext('2d');
destinationCanvasContext.drawImage(sourceCanvasWebGL, 0, 0);

通过一些谷歌搜索(通过canvas.toDataURL将画布保存为图像结果为黑色矩形),我发现因为WebGL在绘制时使用了2个缓冲区,所以我复制了旧缓冲区的空内容。

问题通过在用于进行WebGL绘制的代码中设置preserveDrawingBuffer:true来解决。

sourceCanvasWebGL.getContext(“webgl2”,{preserveDrawingBuffer:true})

P.S.作为替代方案,您可以在渲染画布后立即制作图像副本。如果是这样,您不需要preserveDrawingBuffer。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接