Canvas to DataURL()返回空白图像
Canvas toDataURL() returns blank image
我使用glfx.js来编辑我的图像,但当我试图使用toDataURL()
函数获取该图像的数据时,我会得到一个空白图像(宽度与原始图像相同)。
奇怪的是,在Chrome中,脚本运行得非常完美。
我想提到的是,使用onload事件将图像加载到canvas
中:
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);
}
我的图像的路径也在同一个域上;
(在Firefox中)问题是当我点击保存按钮时。Chrome返回预期结果,但Firefox返回以下内容:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA7YAAAIWCAYAAABjkRHCAAAHxklEQVR4nO3BMQEAAADCoPVPbQZ/oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
... [ lots of A s ] ...
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAzwD6aAABkwvPRgAAAABJRU5ErkJggg==
是什么原因导致了这种结果?我该如何解决?
在绘制到画布的时间和调用toDataURL
的时间之间很可能存在一些异步事件。默认情况下,画布在每次合成后都会被清除。通过在中使用preserveDrawingBuffer: true
创建WebGL上下文来防止画布被清除
var gl = canvas.getContext("webgl", {preserveDrawingBuffer: true});
或者确保在退出用于渲染的任何事件之前调用了toDataURL。例如,如果你做这个
function render() {
drawScene();
requestAnimationFrame(render);
}
render();
还有其他地方做这个
someElement.addEventListener('click', function() {
var data = someCanvas.toDataURL();
}, false);
这两个事件animation frame
和click
不同步,并且在调用它们之间可以清除画布。注意:画布不会显示为已清除,因为它是双缓冲的,但缓冲区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: false
有什么意义?它可以明显更快,尤其是在移动设备上,不必保留绘图缓冲区。另一种方法是浏览器需要两份画布。你正在绘制的对象和它正在显示的对象。它有两种方法来处理这两个缓冲区。(A) 双缓冲器。让您绘制到一个,显示另一个,在渲染完成时交换缓冲区,这是从退出发出绘制命令的任何事件中推断出来的(B)复制您正在绘制的缓冲区的内容以创建正在显示的缓冲区。交换比复制快得多。因此,交换是默认的。实际发生的事情取决于浏览器。唯一的要求是,如果preserveDrawingBuffer
是false
,则绘制缓冲区在合成后被清除(这是另一个异步事件,因此是不可预测的)。如果preserveDrawingBuffer
是true
,则它必须进行复制,以便保留绘制缓冲区的内容。
请注意,一旦画布具有上下文,它将始终具有相同的上下文。换句话说,假设您更改了初始化WebGL上下文的代码,但仍然希望设置preserveDrawingBuffer: true
至少有两种方法。
先找到画布,在上面获取上下文
因为代码稍后将使用相同的上下文。
<script>
document.querySelector('#somecanvasid').getContext(
'webgl', {preserveDrawingBuffer: true});
</script>
<script src="script/that/will/use/somecanvasid.js"></script>
因为您已经为画布创建了一个上下文,所以无论后面的脚本是什么,都将获得相同的上下文。
增加getContext
<script>
HTMLCanvasElement.prototype.getContext = function(origFn) {
return function(type, attributes) {
if (type === 'webgl') {
attributes = Object.assign({}, attributes, {
preserveDrawingBuffer: true,
});
}
return origFn.call(this, type, attributes);
};
}(HTMLCanvasElement.prototype.getContext);
</script>
<script src="script/that/will/use/webgl.js"></script>
在这种情况下,在扩充getContext
之后创建的任何webgl上下文都会将preserveDrawingBuffer
设置为true。
- 为什么我的javascript地理编码函数返回空白结果
- html5 canvas toDataURL 返回空白图像
- 脚本只在jQueryAJAX中返回空白
- 试图在网站上抓取谷歌地图api生成的动态数据,但正常抓取返回空白
- AngularJS 指令范围和$compile - 返回空白的变量
- 为什么我的 JavaScript 提升的局部变量返回未定义,但提升的全局变量返回空白
- 按钮 ID 返回空白
- Canvas to DataURL()返回空白图像
- document.body.style.marginTop 在 JS 中返回空白字符串
- Javascript-element.style.left返回空白
- servlet发出的警报返回空白页面
- 联系表单返回空白页
- myDiv.style.display在主样式表中设置时返回空白
- 初始化jQuery返回空白页的数据表
- c# WebBrowser运行Javascript -返回空白页面与Javascript的结果-为什么
- Node.js -第一个请求返回空白,第二个请求返回数据
- Blob图像返回空白图像
- 为什么ExtJs 5.1中的Tagfield对于getDisplayValue()总是返回空白
- ajaxBeginForm在IE9中返回空白视图
- js样式的属性返回空白