的最大尺寸元素

发布于 2024-11-09 05:19:57 字数 170 浏览 0 评论 0原文

我正在使用高度为 6001000 像素、宽度为数十或数十万像素的画布元素。然而,在一定数量的像素(显然未知)之后,画布不再显示我用 JS 绘制的形状。

有谁知道有没有限制?

在 Chrome 12 和 Firefox 4 中进行了测试。

I'm working with a canvas element with a height of 600 to 1000 pixels and a width of several tens or hundreds of thousands of pixels. However, after a certain number of pixels (obviously unknown), the canvas no longer display shapes I draw with JS.

Does anyone know if there's a limit?

Tested both in Chrome 12 and Firefox 4.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

孤檠 2024-11-16 05:19:57

更新于 10/13/2014

所有测试的浏览器都对画布元素的高度/宽度有限制,但许多浏览器还限制画布元素的总面积。我能够测试的浏览器的限制如下:

Chrome:

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

Firefox:

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

IE:

最大高度/宽度:8,192 像素
最大面积:不适用

IE 移动设备:

最大高度/宽度:4,096 像素
最大区域:不适用

其他:

我目前无法测试其他浏览器。有关其他限制,请参阅本页上的其他答案。


超过大多数浏览器上的最大长度/宽度/面积会导致画布无法使用。 (它将忽略任何绘制命令,即使在可用区域中也是如此。)IE 和 IE Mobile 将遵守可用空间内的所有绘制命令。

Updated 10/13/2014

All tested browsers have limits to the height/width of canvas elements, but many browsers also limit the total area of the canvas element. The limits are as follows for the browsers I'm able to test:

Chrome:

Maximum height/width: 32,767 pixels
Maximum area: 268,435,456 pixels (e.g., 16,384 x 16,384)

Firefox:

Maximum height/width: 32,767 pixels

Maximum area: 472,907,776 pixels (e.g., 22,528 x 20,992)

IE:

Maximum height/width: 8,192 pixels
Maximum area: N/A

IE Mobile:

Maximum height/width: 4,096 pixels
Maximum area: N/A

Other:

I'm not able to test other browsers at this time. Refer to the other answers on this page for additional limits.


Exceeding the maximum length/width/area on most browsers renders the canvas unusable. (It will ignore any draw commands, even in the usable area.) IE and IE Mobile will honor all draw commands within the usable space.

秉烛思 2024-11-16 05:19:57

接受的答案已经过时且不完整。

浏览器施加不同的画布大小限制,但这些限制通常会根据可用的平台和硬件而变化。这使得很难做出像“[browser] 的最大画布 [area/height/width][value]”这样的语句,因为[value] 可以根据操作系统、可用 RAM 或 GPU 类型进行更改。

有两种处理大型 HTML 元素的方法:

  1. 将画布尺寸限制为已知可在所有支持的平台上使用的尺寸。
  2. 在渲染之前以编程方式确定客户端上的画布限制。

那些希望以编程方式确定客户端画布限制的人应该考虑使用 canvas-size

来自文档:

HTML canvas 元素受到现代和传统的广泛支持
浏览器,但每个浏览器和平台组合都有独特的
超出大小限制将使画布无法使用。
不幸的是,浏览器没有提供一种方法来确定它们的内容
限制是,他们也不提供任何类型的反馈
创建了无法使用的画布。这使得使用大画布
元素是一个挑战,特别是对于支持
各种浏览器和平台。

这个微型图书馆提供了一个物体的最大面积、高度和宽度。
浏览器支持的 HTML canvas 元素以及
测试自定义画布尺寸。通过在之前收集这些信息
创建新的画布元素后,应用程序能够可靠地设置
画布尺寸在每个尺寸限制内
浏览器/平台。

此处提供了各种平台和浏览器组合的测试结果:

完全公开,我是该库的作者。我在 2014 年创建了它,最近重新审视了一个新的画布相关项目的代码。我很惊讶地发现 2018 年同样缺乏检测画布大小限制的可用工具,因此我更新了代码并发布了它,并希望它可以帮助其他遇到类似问题的人。

The accepted answer is outdated and incomplete.

Browsers impose different canvas size limitations, but these limitations often change based on the platform and hardware available. This makes it difficult to make statements like "the maximum canvas [area/height/width] of [browser] is [value]" because [value] can change based the operating system, available RAM, or GPU type.

There are two approaches to working with large HTML <canvas> elements:

  1. Limit canvas dimensions to those known to work on all supported platforms.
  2. Programmatically determine canvas limitations on the client before rendering.

Those looking to programmatically determine canvas limitations on the client should consider using canvas-size.

From the docs:

The HTML canvas element is widely supported by modern and legacy
browsers, but each browser and platform combination imposes unique
size limitations that will render a canvas unusable when exceeded.
Unfortunately, browsers do not provide a way to determine what their
limitations are, nor do they provide any kind of feedback after an
unusable canvas has been created. This makes working with large canvas
elements a challenge, especially for applications that support a
variety of browsers and platforms.

This micro-library provides the maximum area, height, and width of an
HTML canvas element supported by the browser as well as the ability to
test custom canvas dimensions. By collecting this information before a
new canvas element is created, applications are able to reliably set
canvas dimensions within the size limitations of each
browser/platform.

Test results for a variety of platform and browser combinations are available here:

Full disclosure, I am the author of the library. I created it back in 2014 and recently revisited the code for a new canvas-related project. I was surprised to find the same lack of available tools for detecting canvas size limitations in 2018 so I updated code, released it, and hope it helps others running into similar issues.

望喜 2024-11-16 05:19:57

我在 Firefox 上遇到内存不足错误,画布高度大于 8000,chrome 似乎可以处理更高的高度,至少到 32000。

编辑:运行更多测试后,我发现 Firefox 16.0 出现一些非常奇怪的错误。 2.

首先,我似乎从内存中(在 javascript 中创建)画布中获得了与 html 声明的画布不同的行为。

其次,如果您没有正确的 html 标签和元字符集,画布可能会被限制为 8196,否则您可以达到 32767。

第三,如果您获取画布的 2d 上下文,然后更改画布大小,您也可能被限制为 8196。只需在获取 2d 上下文之前设置画布大小即可让您拥有高达 32767 的画布大小,而不会出现内存错误。

我无法始终如一地获得内存错误,有时仅在第一页加载时出现,然后随后的高度更改才有效。这是我用 http://pastebin.com/zK8nZxdE 测试的 html 文件。

I've ran into out of memory errors on Firefox with canvas heights greater than 8000, chrome seems to handle much higher, at least to 32000.

EDIT: After running some more tests, I've found some very strange errors with Firefox 16.0.2.

First, I seem to get different behavior from in memory (created in javascript) canvas as opposed to html declared canvas.

Second, if you don't have the proper html tag and meta charset, the canvas might be restricted to 8196, otherwise you can go up to 32767.

Third, if you get the 2d context of the canvas and then change the canvas size, you might be restricted to 8196 as well. Simply setting the canvas size before grabbing the 2d context allows you to have up to 32767 without getting memory errors.

I haven't been able to consistently get the memory errors, sometimes it's only on the first page load, and then subsequent height changes work. This is the html file I was testing with http://pastebin.com/zK8nZxdE.

一身骄傲 2024-11-16 05:19:57

iOS 最大画布尺寸(宽 x 高):

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

2014 年 3 月测试。

iOS max canvas size (width x height):

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

tested on march 2014.

情感失落者 2024-11-16 05:19:57

扩展一下 @FredericCharette 的答案:
根据 safari 的内容指南在“了解 iOS 资源限制”部分下:

对于 RAM 小于 256 MB 的设备,画布元素的最大尺寸为 3 兆像素;对于 RAM 大于或等于 256 MB 的设备,画布元素的最大尺寸为 5 兆像素

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

5 兆像素画布的示例(宽 x 高):

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

依此类推。

最大的方形画布是(“MiB”= 1024x1024 字节):

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

To expand a bit on @FredericCharette answer:
As per safari's content guide under section "Know iOS Resource Limits":

The maximum size for a canvas element is 3 megapixels for devices with less than 256 MB RAM and 5 megapixels for devices with greater or equal than 256 MB RAM

Therefore, any size variation of 5242880 (5 x 1024 x 1024) pixels will work on large memory devices, otherwise it's 3145728 pixels.

Example for 5 megapixel canvas (width x height):

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

and so on..

The largest SQUARE canvases are ("MiB" = 1024x1024 Bytes):

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
三生一梦 2024-11-16 05:19:57

根据 w3 规范,宽度/高度接口是一个无符号的long - 所以 0 到 4,294,967,295 (如果我没记错的话 - 可能会少一些)。

编辑:奇怪的是,它说 unsigned long,但它测试显示只是一个正常的 long 值作为最大值:2147483647。 Jsfiddle - 47 有效,但达到 48 后会恢复为默认值。

According to w3 specs, the width/height interface is an unsigned long - so 0 to 4,294,967,295 (if I remember that number right -- might be off a few).

EDIT: Strangely, it says unsigned long, but it testing shows just a normal long value as the max: 2147483647. Jsfiddle - 47 works but up to 48 and it reverts back to default.

哑剧 2024-11-16 05:19:57

即使画布允许您输入 height=2147483647,当您开始绘图时,不会发生任何事情

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

Even though the canvas will allow you to put height=2147483647, when you start drawing, nothing will happen

Drawing happens only when I bring the height back to 32767

一场春暖 2024-11-16 05:19:57

iOS 有不同的限制。

使用 iOS 7 模拟器,我能够演示限制为 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

但是如果我将画布大小微移一行像素:

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

iOS has different limits.

Using the iOS 7 simulator I was able to demonstrate the limit is 5MB like this:

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

but if I nudge the canvas size up by a single row of pixels:

var canvas = document.createElement('canvas');
canvas.width = 1024 * 5;
canvas.height = 1025;
alert(canvas.toDataURL('image/jpeg'));
// prints "data:," - a broken dataURL
憧憬巴黎街头的黎明 2024-11-16 05:19:57

在电脑上-
我不认为有限制,但是是的,你可能会出现内存不足的异常。

在移动设备上-
以下是移动设备画布的限制:-

对于 RAM 小于 256 MB 的设备,画布元素的最大尺寸为 3 兆像素;对于 RAM 大于或等于 256 MB 的设备,画布元素的最大尺寸为 5 兆像素。

例如 - 如果你想支持苹果较旧的硬件,你的画布大小不能超过 2048×1464。

希望这些资源能帮助您摆脱困境。

On PC-
I don't think there is a restriction but yes you can get out of memory exception.

On Mobile devices-
Here is the restrictions for the canvas for mobile devices:-

The maximum size for a canvas element is 3 megapixels for devices with less than 256 MB RAM and 5 megapixels for devices with greater or equal than 256 MB RAM.

So for example - if you want to support Apple’s older hardware, the size of your canvas cannot exceed 2048×1464.

Hope these resources will help you to pull you out.

ζ澈沫 2024-11-16 05:19:57

当您使用 WebGL 画布时,浏览器(包括桌面浏览器)将对底层缓冲区的大小施加额外的限制。即使您的画布很大,例如 16,000x16,000,大多数浏览器也会渲染较小的(假设为 4096x4096)图片,并将其放大。这可能会导致丑陋的像素化等。

我已经编写了一些代码来使用指数搜索来确定最大大小(如果有人需要的话)。 defineMaxCanvasSize() 是您感兴趣的函数。

function makeGLCanvas()
{
    // Get A WebGL context
    var canvas = document.createElement('canvas');
    var contextNames = ["webgl", "experimental-webgl"];
    var gl = null;
    for (var i = 0; i < contextNames.length; ++i)
    {
        try
        {
            gl = canvas.getContext(contextNames[i], {
                // Used so that the buffer contains valid information, and bytes can
                // be retrieved from it. Otherwise, WebGL will switch to the back buffer
                preserveDrawingBuffer: true
            });
        }
        catch(e) {}
        if (gl != null)
        {
            break;
        }
    }
    if (gl == null)
    {
        alert("WebGL not supported.\nGlobus won't work\nTry using browsers such as Mozilla " +
            "Firefox, Google Chrome or Opera");
        // TODO: Expecting that the canvas will be collected. If that is not the case, it will
        // need to be destroyed somehow.
        return;
    }

    return [canvas, gl];
}

// From Wikipedia
function gcd(a,b) {
    a = Math.abs(a);
    b = Math.abs(b);
    if (b > a) {var temp = a; a = b; b = temp;}
    while (true) {
        if (b == 0) return a;
        a %= b;
        if (a == 0) return b;
        b %= a;
    }
}

function isGlContextFillingTheCanvas(gl) {
    return gl.canvas.width == gl.drawingBufferWidth && gl.canvas.height == gl.drawingBufferHeight;
}

// (See issue #2) All browsers reduce the size of the WebGL draw buffer for large canvases 
// (usually over 4096px in width or height). This function uses a varian of binary search to
// find the maximum size for a canvas given the provided x to y size ratio.
//
// To produce exact results, this function expects an integer ratio. The ratio will be equal to:
// xRatio/yRatio.
function determineMaxCanvasSize(xRatio, yRatio) {
    // This function works experimentally, by creating an actual canvas and finding the maximum
    // value, the browser allows.
    [canvas, gl] = makeGLCanvas();

    // Reduce the ratio to minimum
    gcdOfRatios = gcd(xRatio, yRatio);
    [xRatio, yRatio] = [xRatio/gcdOfRatios, yRatio/gcdOfRatios];

    // if the browser cannot handle the minimum ratio, there is not much we can do
    canvas.width = xRatio;
    canvas.height = yRatio;

    if (!isGlContextFillingTheCanvas(gl)) {
        throw "The browser is unable to use WebGL canvases with the specified ratio: " + 
            xRatio + ":" + yRatio;
    }

    // First find an upper bound
    var ratioMultiple = 1;  // to maintain the exact ratio, we will keep the multiplyer that
                            // resulted in the upper bound for the canvas size
    while (isGlContextFillingTheCanvas(gl)) {
        canvas.width *= 2;
        canvas.height *= 2;
        ratioMultiple *= 2;
    }

    // Search with minVal inclusive, maxVal exclusive
    function binarySearch(minVal, maxVal) {
        if (minVal == maxVal) {
            return minVal;
        }

        middle = Math.floor((maxVal - minVal)/2) + minVal;

        canvas.width = middle * xRatio;
        canvas.height = middle * yRatio;

        if (isGlContextFillingTheCanvas(gl)) {
            return binarySearch(middle + 1, maxVal);
        } else {
            return binarySearch(minVal, middle);
        }
    }

    ratioMultiple = binarySearch(1, ratioMultiple);
    return [xRatio * ratioMultiple, yRatio * ratioMultiple];
}

也在jsfiddle https:// /jsfiddle.net/1sh47wfk/1/

When you are using WebGL canvases, the browsers (including the desktop ones) will impose extra limits on the size of the underlying buffer. Even if your canvas is big, e.g. 16,000x16,000, most browsers will render a smaller (let's say 4096x4096) picture, and scale it up. That might cause ugly pixelating, etc.

I have written some code to determine that maximum size using exponential search, if anyone ever needs it. determineMaxCanvasSize() is the function you are interested in.

function makeGLCanvas()
{
    // Get A WebGL context
    var canvas = document.createElement('canvas');
    var contextNames = ["webgl", "experimental-webgl"];
    var gl = null;
    for (var i = 0; i < contextNames.length; ++i)
    {
        try
        {
            gl = canvas.getContext(contextNames[i], {
                // Used so that the buffer contains valid information, and bytes can
                // be retrieved from it. Otherwise, WebGL will switch to the back buffer
                preserveDrawingBuffer: true
            });
        }
        catch(e) {}
        if (gl != null)
        {
            break;
        }
    }
    if (gl == null)
    {
        alert("WebGL not supported.\nGlobus won't work\nTry using browsers such as Mozilla " +
            "Firefox, Google Chrome or Opera");
        // TODO: Expecting that the canvas will be collected. If that is not the case, it will
        // need to be destroyed somehow.
        return;
    }

    return [canvas, gl];
}

// From Wikipedia
function gcd(a,b) {
    a = Math.abs(a);
    b = Math.abs(b);
    if (b > a) {var temp = a; a = b; b = temp;}
    while (true) {
        if (b == 0) return a;
        a %= b;
        if (a == 0) return b;
        b %= a;
    }
}

function isGlContextFillingTheCanvas(gl) {
    return gl.canvas.width == gl.drawingBufferWidth && gl.canvas.height == gl.drawingBufferHeight;
}

// (See issue #2) All browsers reduce the size of the WebGL draw buffer for large canvases 
// (usually over 4096px in width or height). This function uses a varian of binary search to
// find the maximum size for a canvas given the provided x to y size ratio.
//
// To produce exact results, this function expects an integer ratio. The ratio will be equal to:
// xRatio/yRatio.
function determineMaxCanvasSize(xRatio, yRatio) {
    // This function works experimentally, by creating an actual canvas and finding the maximum
    // value, the browser allows.
    [canvas, gl] = makeGLCanvas();

    // Reduce the ratio to minimum
    gcdOfRatios = gcd(xRatio, yRatio);
    [xRatio, yRatio] = [xRatio/gcdOfRatios, yRatio/gcdOfRatios];

    // if the browser cannot handle the minimum ratio, there is not much we can do
    canvas.width = xRatio;
    canvas.height = yRatio;

    if (!isGlContextFillingTheCanvas(gl)) {
        throw "The browser is unable to use WebGL canvases with the specified ratio: " + 
            xRatio + ":" + yRatio;
    }

    // First find an upper bound
    var ratioMultiple = 1;  // to maintain the exact ratio, we will keep the multiplyer that
                            // resulted in the upper bound for the canvas size
    while (isGlContextFillingTheCanvas(gl)) {
        canvas.width *= 2;
        canvas.height *= 2;
        ratioMultiple *= 2;
    }

    // Search with minVal inclusive, maxVal exclusive
    function binarySearch(minVal, maxVal) {
        if (minVal == maxVal) {
            return minVal;
        }

        middle = Math.floor((maxVal - minVal)/2) + minVal;

        canvas.width = middle * xRatio;
        canvas.height = middle * yRatio;

        if (isGlContextFillingTheCanvas(gl)) {
            return binarySearch(middle + 1, maxVal);
        } else {
            return binarySearch(minVal, middle);
        }
    }

    ratioMultiple = binarySearch(1, ratioMultiple);
    return [xRatio * ratioMultiple, yRatio * ratioMultiple];
}

Also in a jsfiddle https://jsfiddle.net/1sh47wfk/1/

開玄 2024-11-16 05:19:57

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

已知的 iOS/Safari 限制

例如,我有一个 6400x6400px 的画布缓冲区,上面绘制了数据。通过跟踪/导出内容并在其他浏览器上进行测试,我发现一切都很好。但在 Safari 上,它会跳过将此特定缓冲区绘制到我的主上下文上。

The limitations for Safari (all platforms) are much lower.

Known iOS/Safari Limitations

For example, I had a 6400x6400px canvas buffer with data drawn onto it. By tracing/ exporting the content and by testing on other browsers, I was able to see that everything was fine. But on Safari, it would skip the drawing of this specific buffer onto my main context.

┊风居住的梦幻卍 2024-11-16 05:19:57

我尝试以编程方式找出限制:设置画布大小从 35000 开始,逐步减少 100 直到找到有效大小。在每一步中写入右下像素然后读取它。它有效 - 谨慎行事。

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

但是,如果像 get_max_canvas_size() 这样没有宽度或高度的情况下调用,则创建的画布太大,读取单个像素颜色非常慢,并且在 IE 中会导致严重挂起。

如果可以在不读取像素值的情况下以某种方式完成类似的测试,那么速度是可以接受的。

当然,检测最大尺寸的最简单方法是查询最大宽度和高度的某种本机方法。但 Canvas 是“一种生活标准”,所以也许有一天它会出现。

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;
  }
}

I tried to programmatically figure out the limit: setting canvas size starting from 35000, stepping down by 100 until valid size is found. In every step writing the right-bottom pixel and then reading it. It works - with caution.

The speed is acceptable if either width or height is set to some low value (eg. 10-200) this way: get_max_canvas_size('height', 20).

But if called without width or height like get_max_canvas_size(), the created canvas is so big that reading SINGLE pixel color is very slow, and in IE causes serious hang.

If this like test could be done someway without reading pixel value, the speed would be acceptable.

Of course the easiest way to detect maximum size would be some native way to query the max width and height. But Canvas is 'a living standard', so may be it is coming some day.

http://jsfiddle.net/timo2012/tcg6363r/2/ (Be aware! Your browser may hang!)

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;
  }
}
初懵 2024-11-16 05:19:57

您可以将其分块,并在 javascript 中根据需要自动添加尽可能多的较小画布,并在适当的画布上绘制元素。您最终可能仍然会耗尽内存,但会达到单个画布的限制。

You could chunk it and in javascript auto add as many smaller canvases as needed and draw the elements on the appropriate canvas. You may still run out of memory eventually but would get you by the single canvas limit.

能怎样 2024-11-16 05:19:57

我不知道如何在不迭代的情况下检测最大可能的尺寸,但是您可以通过填充像素然后读取颜色来检测给定的画布尺寸是否有效。如果画布尚未渲染,那么您返回的颜色将不匹配。 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);

I don't know how to detect the max possible size without itteration, but you can detect if a given canvas size works by filling a pixel and then reading the colour back out. If the canvas has not rendered then the color you get back will not match. W

partial code:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文