Canvas toDataURL()仅在Firefox中返回空白图片 [英] Canvas toDataURL() returns blank image only in Firefox

查看:2133
本文介绍了Canvas toDataURL()仅在Firefox中返回空白图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 glfx.js 编辑我的图片,但我尝试取得该图片的资料时使用 toDataURL()函数我得到一个空白图像(宽度与原始图像相同)。



奇怪的是,在Chrome脚本工作完美。



我想要提到的是图像加载在画布使用onload事件:

  img.onload = function(){

try {
canvas = fx.canvas();
} catch(e){
alert(e);
return;
}

//将图像转换为纹理
texture = canvas.texture(img);

//绘制和更新canvas
canvas.draw(texture).update();

//用canvas替换图片
img.parentNode.insertBefore(canvas,img);
img.parentNode.removeChild(img)

}

此外,我的映像路径在同一个域上; p>

问题(在Firefox中)是我点击保存按钮。镀铬返回预期的结果,但Firefox返回此:

 数据:图像/ PNG; BASE64,iVBORw0KGgoAAAANSUhEUgAAA7YAAAIWCAYAAABjkRHCAAAHxklEQVR4nO3BMQEAAADCoPVPbQZ / oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
。 .. [许多A S的] ...
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAzwD6aAABkwvPRgAAAABJRU5ErkJggg ==

这是什么原因这个结果和我如何解决它?

解决方案

很可能有一些异步事件之间的时间你画到画布和时间你调用 toDataURL 。默认情况下,画布在每个复合后清除。无论是防止画布通过创建与 preserveDrawingBuffer WebGL的情况下被清除:真正的



  var gl = canvas.getContext(webgl,{preserveDrawingBuffer:true}); 

或确保在退出您要使用的任何事件之前调用toDataURL。例如,如果你这样做

  function render(){
drawScene
requestAnimationFrame(render);
}
render();

其他地方

  someElement.addEventListener('click',function(){
var data = someCanvas.toDataURL();
},false);

这两个事件,动画框架单击不同步,并且画布可以在调用它们之间清除。注意:画布不会出现清除,因为它是双缓冲,但缓冲区toDataURL和影响该缓冲区正在查看的其他命令被清除。



解决方案是使用 preserveDrawingBuffer 或者在与渲染相同的事件中调用 toDataURL 。例如

  var captureFrame = false; 

function render(){
drawScene();

if(captureFrame){
captureFrame = false;
var data = someCanvas.toDataURL();
...
}

requestAnimationFrame(render);
}
render();

someElement.addEventListener('click',function(){
captureFrame = true;
},false);



什么是 preserveDrawingBuffer点:假这是默认值?它可以明显更快,特别是在移动设备上,不必保留绘图缓冲区。另一种方式来看看它是浏览器需要2副本的画布。你正在绘制的和它显示的一个。它有两种方法来处理这两个缓冲区。 (A)双缓冲液。让你绘制一个,显示另一个,交换缓冲区,当你完成渲染时,从退出任何发出绘制命令的事件推断(B)复制你正在绘制的缓冲区的内容做正在显示的缓冲区。交换比复制要快得多。因此,交换是默认值。这取决于浏览器实际发生的事情。唯一的要求是,如果 preserveDrawingBuffer 的绘制缓冲区得到复合后(清除这是另一种异步事件,因此无法预测的),如果 preserveDrawingBuffer 真正那么它必须复制这样的drawingbuffer的内容被保留下来。


I'm using glfx.js to edit my image but when I'm trying to get that image's data using the toDataURL() function I get a blank image (width the same size as the original image).

The strange thing is that in Chrome the script works perfect.

What I want to mention is that the image is loaded in canvas using the onload event:

           img.onload = function(){

                try {
                    canvas = fx.canvas();
                } catch (e) {
                    alert(e);
                    return;
                }

                // convert the image to a texture
                texture = canvas.texture(img);

                // draw and update canvas
                canvas.draw(texture).update();

                // replace the image with the canvas
                img.parentNode.insertBefore(canvas, img);
                img.parentNode.removeChild(img);

            }

Also my image's path is on the same domain;

The problem (in Firefox) is when i hit the save button. Chrome returns the expected result but Firefox return this:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA7YAAAIWCAYAAABjkRHCAAAHxklEQVR4nO3BMQEAAADCoPVPbQZ/oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
... [ lots of A s ] ... 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAzwD6aAABkwvPRgAAAABJRU5ErkJggg==

What could cause this result and how can I fix it?

解决方案

Most likely there's some async event between the time you draw to the canvas and the time you call toDataURL. By default the canvas is cleared after every composite. Either prevent the canvas from being cleared by creating the WebGL context with preserveDrawingBuffer: true as in

var gl = canvas.getContext("webgl", {preserveDrawingBuffer: true});

or make sure toDataURL is called before exiting whatever event you're using to render. For example if you do this

function render() {
  drawScene(); 
  requestAnimationFrame(render);
}
render();

And somewhere else do this

someElement.addEventListener('click', function() {
  var data = someCanvas.toDataURL();
}, false);

Those 2 events, the animation frame, and the click are not in sync and the canvas may be cleared between calling them. Note: The canvas won't appear cleared as it's double buffered but the buffer toDataURL and other commands that effect that buffer are looking at is cleared.

The solution is either use preserveDrawingBuffer or make your call to toDataURL inside the same event as rendering. For example

var captureFrame = false;

function render() {
  drawScene(); 

  if (captureFrame) {
    captureFrame = false;
    var data = someCanvas.toDataURL();
    ...
  }

  requestAnimationFrame(render);
}
render();

someElement.addEventListener('click', function() {
  captureFrame = true;
}, false);

What's the point of preserveDrawingBuffer: false which is the default? It can be significantly faster, especially on mobile to not have to preserve the drawing buffer. Another way to look at it is the browser needs 2 copies of your canvas. The one you're drawing to and the one it's displaying. It has 2 ways to deal with these 2 buffers. (A) double buffer. Let you draw to one, display the other, swap the buffers when you're done rendering which is inferred from exiting any event that issued draw commands (B) Copy the contents of the buffer you're drawing to do the buffer that's being displayed. Swapping is much faster than copying. So, swapping is the default. It's up to the browser what actually happens. The only requirement is that if preserveDrawingBuffer is false that the drawing buffer get cleared after a composite (which is yet another async event and therefore unpredictable) if preserveDrawingBuffer is true then it must copy so that the drawingbuffer's contents is preserved.

这篇关于Canvas toDataURL()仅在Firefox中返回空白图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆