一个<canvas>元素的最大尺寸

我正在使用高度为600到1000像素,宽度为几十或几十万像素的canvas元素。 但是,在一定数量的像素(显然未知)之后,canvas不再显示用JS绘制的形状。

有谁知道是否有限制? 谢谢。

编辑 :在Chrome 12和Firefox 4中都进行了testing。

更新10/13/2014

所有testing过的浏览器对canvas元素的高度/宽度都有限制,但许多浏览器也限制了canvas元素的总面积。 我可以testing的浏览器的限制如下:

铬:

最大高度/宽度:32,767像素
最大面积:268,435,456像素(如16,384 x 16,384)

火狐:

最大高度/宽度:32,767像素
最大面积:472,907,7​​76像素(例如22,528 x 20,992)

IE:

最大高度/宽度:8,192像素
最大面积:N / A

IE手机:

最大高度/宽度:4096像素
最大面积:N / A

其他:

我目前无法testing其他浏览器。 请参阅本页面上的其他答案以获取更多限制。


超过大多数浏览器的最大长度/宽度/区域会使canvas无法使用。 (即使在可用区域,它也将忽略任何绘图命令。)IE和IE Mobile将在可用空间内执行所有绘图命令。

我已经遇到Firefox的内存错误,canvas高度大于8000,Chrome看起来处理得更高,至less达到32000。

编辑:运行一些更多的testing后,我发现一些Firefox 16.0.2非常奇怪的错误。

首先,我似乎从内存(创build在JavaScript)canvas,而不是HTML声明canvas不同的行为。

其次,如果你没有合适的html标签和元字符集,canvas可能被限制为8196,否则你可以上到32767。

第三,如果你得到了canvas的第二个上下文,然后改变canvas大小,那么你可能也被限制在8196。 在抓取2D上下文之前简单地设置canvas大小,可以让您最多达到32767,而不会出现内存错误。

我一直无法获得内存错误,有时只是在第一页加载,然后后续的高度更改工作。 这是我用http://pastebin.com/zK8nZxdEtesting的html文件。;

iOS最大canvas尺寸(宽x高):

  iPod Touch 16GB = 1448x1448 iPad Mini = 2290x2289 iPhone 3 = 1448x1448 iPhone 5 = 2290x2289 

在2014年3月testing。

在@FredericCharette上展开一些回答:按照“了解iOS资源限制”一节中的Safari浏览器内容指南 :

canvas元素的最大大小为300万像素,对于256 MB RAM以下的设备,对于大于等于256 MB RAM的设备,500万像素

因此,5242880(5 x 1024 x 1024)像素的任何尺寸变化都可用于大型存储设备,否则为3145728像素。

500万像素canvas(宽x高)示例:

 Any total <= 5242880 -------------------- 5 x 1048576 ~= 5MP (1048576 = 1024 x 1024) 50 x 104857 ~= 5MP 500 x 10485 ~= 5MP 

等等..

最大的SQUAREcanvas是(“MiB”= 1024×1024字节):

 device < 256 MiB device >= 256 MiB iPhone 6 [not confirmed] ----------------- ----------------- --------------------- <= 3145728 pixels <= 5242880 pixels <= 16 x 1024 x 1024 p 1773 x 1773 2289 x 2289 4096 x 4096 

根据w3的规格 ,宽度/高度界面是一个无符号的长 – 所以0至4,294,967,295(如果我记得数字是正确的 – 可能是几个)。

编辑:奇怪的是,它说无符号长,但它testing显示只是一个正常的长期价值作为最大:2147483647. Jsfiddle – 47作品,但最多48,它恢复到默认。

即使canvas可以让你把高度= 2147483647,当你开始绘画时,什么都不会发生

只有当我把高度恢复到32767时,绘图才会发生

iOS有不同的限制。

使用iOS 7模拟器,我能够certificate这样的限制是5MB:

 var canvas = document.createElement('canvas'); canvas.width = 1024 * 5; canvas.height = 1024; alert(canvas.toDataURL('image/jpeg').length); // prints "110087" - the expected length of the dataURL 

但是如果我将canvas大小向上移动一行像素:

 var canvas = document.createElement('canvas'); canvas.width = 1024 * 5; canvas.height = 1025; alert(canvas.toDataURL('image/jpeg')); // prints "data:," - a broken dataURL 

在PC-
我不认为有一个限制,但是你可以解决内存exception。

在移动设备上 –
以下是移动设备的canvas限制:

对于小于256 MB RAM的设备,canvas元素的最大尺寸为300万像素,对于大于或等于256 MB RAM的设备,最大尺寸为500万像素。

举个例子 – 如果你想支持苹果的老硬件,你的canvas的大小不能超过2048×1464。

希望这些资源能帮助你把你拉出来。

我尝试以编程方式计算出限制:设置从35000开始的canvas大小,逐步减小100,直到find有效大小。 在写下右下像素的每一步中,然后读取它。 它的工作 – 谨慎。

如果宽度或高度被设置为某个低值(例如10-200),速度是可以接受的: get_max_canvas_size('height', 20)

但是如果调用没有像get_max_canvas_size()那样的宽度或高度,所创build的canvas如此之大以至于读取单色像素颜色非常缓慢,并且在IE中导致严重的挂起。

如果像这样的testing可以在不读取像素值的情况下完成,速度将是可以接受的。

当然,最简单的方法来检测最大的大小将是一些本地的方式来查询最大的宽度和高度。 但帆布是一个“生活水平”,所以可能有一天会来临。

http://jsfiddle.net/timo2012/tcg6363r/2/ (注意!您的浏览器可能会挂起!

 if (!Date.now) { Date.now = function now() { return new Date().getTime(); }; } var t0 = Date.now(); //var size = get_max_canvas_size('width', 200); var size = get_max_canvas_size('height', 20); //var size = get_max_canvas_size(); var t1 = Date.now(); var c = size.canvas; delete size.canvas; $('body').append('time: ' + (t1 - t0) + '<br>max size:' + JSON.stringify(size) + '<br>'); //$('body').append(c); function get_max_canvas_size(h_or_w, _size) { var c = document.createElement('canvas'); if (h_or_w == 'height') h = _size; else if (h_or_w == 'width') w = _size; else if (h_or_w && h_or_w !== 'width' && h_or_w !== 'height' || !window.CanvasRenderingContext2D) return { width: null, height: null }; var w, h; var size = 35000; var cnt = 0; if (h_or_w == 'height') w = size; else if (h_or_w == 'width') h = size; else { w = size; h = size; } if (!valid(w, h)) for (; size > 10; size -= 100) { cnt++; if (h_or_w == 'height') w = size; else if (h_or_w == 'width') h = size; else { w = size; h = size; } if (valid(w, h)) break; } return { width: w, height: h, iterations: cnt, canvas: c }; function valid(w, h) { var t0 = Date.now(); var color, p, ctx; c.width = w; c.height = h; if (c && c.getContext) ctx = c.getContext("2d"); if (ctx) { ctx.fillStyle = "#ff0000"; try { ctx.fillRect(w - 1, h - 1, 1, 1); p = ctx.getImageData(w - 1, h - 1, 1, 1).data; } catch (err) { console.log('err'); } if (p) color = p[0] + '' + p[1] + '' + p[2]; } var t1 = Date.now(); if (color == '25500') { console.log(w, h, true, t1 - t0); return true; } console.log(w, h, false, t1 - t0); return false; } } 

Safari(所有平台)的限制要低得多。

已知的iOS / Safari限制

例如,我有一个6400x6400px的canvas缓冲区,并在其上绘制数据。 通过跟踪/导出内容并在其他浏览器上testing,我可以看到一切都很好。 但在Safari上,它将跳过此特定缓冲区的绘制到我的主要上下文。

你可以大块,并在JavaScript自动添加尽可能多的小canvas,并在适当的canvas上绘制元素。 你最终可能还是用尽了内存,但是会受到单一的canvas限制。

我不知道如何在没有迭代的情况下检测最大可能的大小,但是您可以通过填充像素然后再读取颜色来检测给定的canvas大小是否工作。 如果canvas没有渲染,则返回的颜色将不匹配。 w ^

部分代码:

 function rgbToHex(r, g, b) { if (r > 255 || g > 255 || b > 255) throw "Invalid color component"; return ((r << 16) | (g << 8) | b).toString(16); } var test_colour = '8ed6ff'; working_context.fillStyle = '#' + test_colour; working_context.fillRect(0,0,1,1); var colour_data = working_context.getImageData(0, 0, 1, 1).data; var colour_hex = ("000000" + rgbToHex(colour_data[0], colour_data[1], colour_data[2])).slice(-6);