<canvas>要素の最大サイズ


112

私は、高さcanvas要素で働いている6001000ピクセルとピクセル数万あるいは数百の幅。ただし、一定数のピクセル(明らかに不明)の後、キャンバスにJSで描画した形状が表示されなくなります。

制限があるかどうか誰か知っていますか?

Chrome 12とFirefox 4の両方でテスト済み。


2
@Šime彼は言ったtens OR hundreds of thousands...
Tadeck

6
私もこれを経験します。8000x8000のキャンバスで問題なく動作しますが、大きくするとコンテンツが消えて描画されなくなります。iPadで動作しないサイズは、はるかに小さくなります。なんらかのメモリ制限があるのでしょうか。
ジョシュア

28
2年前の自分のコメントを見つけて、同じ問題をまだ解決していないのは奇妙です。
ジョシュア

4
@ジョシュア、そしてまだ一年後!
Eugene Yu

1
問題は、これらのエラーまたはより適切な警告をどのようにキャッチするかです。デバイスのハードウェアを検出できないため、エラーに対応する必要があります。
br4nnigan 2017

回答:


115

2014年10月13日更新

テストされたすべてのブラウザーには、キャンバス要素の高さ/幅に制限がありますが、多くのブラウザーはキャンバス要素の総面積も制限します。テストできるブラウザの制限は次のとおりです。

クロム:

最大の高さ/幅: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 Mobile:

最大の高さ/幅:4,096ピクセル
最大領域:該当なし

その他:

現在、他のブラウザをテストすることはできません。その他の制限については、このページの他の回答を参照してください。


ほとんどのブラウザで最大長/幅/面積を超えると、キャンバスが使用できなくなります。(使用可能な領域でも、描画コマンドは無視されます。)IEおよびIE Mobileは、使用可能なスペース内のすべての描画コマンドを受け入れます。


3
したがって、関連する質問...許可された最大値より大きいキャンバスが必要な場合、制限を回避するにはどうすればよいですか?
アロス

2
@aroth、私は複数の積み重ねられた<canvas>要素を使用し、適切なコンテキストに描画命令を自動的に適用するcanvas APIのラッパーを作成することになりました。
Brandon Gano 2014

1
とても便利に聞こえます。githubにあると思いませんか?
aroth

5
Safari(非iOSバージョン)は、Chrome.Firefoxのように32Kを使用します。また、ラッパーコードの一部を再作成したい場合は、IEのわずかな8K制限のおかげで、私自身のオープンソースバージョンを開始しました: github.com/adam-roth/wrapped-canvas
aroth

7
iPhone 6 PlusのiOS 9.3.1 Safariは、16777216ピクセルの領域に制限されています(たとえば、4096 x 4096)。これは新しいiOSデバイスで一般的な数だと
思う

16

キャンバスの高さが8000を超えるFirefoxでメモリ不足エラーに遭遇しました。Chromeは、少なくとも32000まで、はるかに高い値を処理するようです。

編集:さらにいくつかのテストを実行した後、Firefox 16.0.2でいくつかの非常に奇妙なエラーを見つけました。

まず、htmlで宣言されたキャンバスとは異なり、メモリ内(JavaScriptで作成)のキャンバスとは異なる動作をするようです。

次に、適切なhtmlタグとメタ文字セットがない場合、キャンバスは8196に制限される可能性があります。それ以外の場合は、32767まで設定できます。

3番目に、キャンバスの2Dコンテキストを取得してからキャンバスサイズを変更すると、8196に制限される可能性があります。2Dコンテキストを取得する前にキャンバスサイズを設定するだけで、メモリエラーが発生することなく最大32767を使用できます。

一貫してメモリエラーを取得できませんでした。最初のページの読み込み時だけに発生することがあり、その後の高さの変更が機能します。これは、http://pastebin.com/zK8nZxdEでテストしていたhtmlファイルです。


4
「2番目に、適切なhtmlタグとメタ文字セットがない場合、キャンバスは8196に制限される可能性があります。それ以外の場合は、32767まで移動できます」-ここで適切なhtmlタグとメタ文字セットとはどういう意味ですか?
Jack Aidley、2015年

確かにあなたは8192(2 ^ 13)を意味しますか?8196は奇妙な数です。
jamesdlin

14

iOSの最大キャンバスサイズ(幅x高さ):

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

2014年3月にテスト済み。


これらの値は任意です。サファリのコンテンツガイドを参照する以下の私の投稿を参照してください
dcbarans

11

@FredericCharetteの回答を少し拡張するには:「iOSリソースの制限について」セクションのサファリのコンテンツガイドに従って:

canvas要素の最大サイズは、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

等々..

最大のSQUAREキャンバスは( "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

1
具体的には、iPhone5の制限は3 * 1024 * 1024 = 3145728ピクセルです。(なぜ私のキャンバスはAndroidでは問題ないがiOSでは空白であるのかと思った後、私はこの答えを見つけました。また、stackoverflow.com / questions / 12556198 / … そしてPhonegapアプリを機能させました。)
Magnus Smith

参考までに、Appleは「Safari / Know iOS Resource Limits」から特定のサイズ情報を削除しました。これは、小さな画像を使用して帯域幅を最小限に抑えることに関する一般的なアドバイスにすぎません。
ToolmakerSteve 2017年

matb33 @リミット* 1024 16 * 1024を持っているiPhone 6表示されていることを疑問にコメントで報告
ToolmakerSteve

11

2018年の更新:

時間の経過とともに、キャンバスの制限が変更されました。悲しいことに、変更されていないのは、ブラウザーがCanvas APIを介してキャンバスサイズの制限に関する情報をまだ提供していないという事実です。

プログラムでブラウザーの最大キャンバスサイズを決定したり、カスタムキャンバスディメンションのサポートをテストしたりする場合は、canvas-sizeをチェックしてください。

ドキュメントから:

HTMLのcanvas要素は、最新のブラウザーとレガシーブラウザーで広くサポートされていますが、ブラウザーとプラットフォームの組み合わせごとに固有のサイズ制限があり、超過するとキャンバスが使用できなくなります。残念ながら、ブラウザーは、制限が何であるかを判別する方法を提供していません。また、使用できないキャンバスが作成された後に、フィードバックを提供していません。このため、特にさまざまなブラウザやプラットフォームをサポートするアプリケーションでは、大きなキャンバス要素の操作が困難になります。

このマイクロライブラリは、ブラウザでサポートされているHTMLキャンバス要素の最大領域、高さ、および幅を提供し、カスタムキャンバスのサイズをテストする機能を提供します。新しいcanvas要素が作成される前にこの情報を収集することにより、アプリケーションは、各ブラウザー/プラットフォームのサイズ制限内でキャンバスのサイズを確実に設定できます。

デモリンクとテスト結果は、READMEで入手できます。また、パフォーマンスと仮想マシンの考慮事項について説明している既知の問題のセクションもあります。

完全な開示、私は図書館の著者です。私は2014年にそれを作成し、最近、新しいキャンバス関連プロジェクトのコードを再検討しました。2018年にキャンバスサイズの制限を検出するために利用できるツールが同じように不足していることに驚いたので、コードを更新してリリースし、他の人が同様の問題に遭遇するのを助けることを願っています。


8

w3仕様によると、幅/高さのインターフェイスは符号なしlongなので、0から4,294,967,295までです(その数値を覚えていれば-少しずれているかもしれません)。

EDIT:不思議、それはunsigned long型と言うが、それは最高のように普通のlong値のショーをテスト:2147483647 Jsfiddle - 48に47点の作品が、アップと、それはデフォルトの値に戻ります。


うーん。興味深いですが、15億にも達していません。
seriousdev

編集済み、申し訳ありません(これは最初にテストしないと得られるものです)-表示するjsfiddleを追加しました。
WSkid、

7

キャンバスではheight = 2147483647を配置できますが、描画を開始しても何も起こりません

描画は、高さを32767に戻したときにのみ発生します


7

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

しかし、キャンバスサイズを1行のピクセルだけナッジすると、次のようになります。

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

2
このようなデータは、iOSシミュレーターに基づくべきではありません。
ゾルタン

5

PC
では、制限はないと思いますが、はい、メモリ不足の例外が発生する可能性があります。


モバイルデバイスの場合-モバイルデバイスのキャンバスの制限は次のとおりです。

canvas要素の最大サイズは、RAMが256 MB未満のデバイスでは3メガピクセル、RAMが256 MB以上のデバイスでは5メガピクセルです。

したがって、たとえば、Appleの古いハードウェアをサポートする場合、キャンバスのサイズは2048×1464を超えることはできません。

これらのリソースがあなたを引き出すのに役立つことを願っています。


3

Safari(すべてのプラットフォーム)の制限ははるかに低くなっています。

既知のiOS / Safariの制限

たとえば、6400x6400pxのキャンバスバッファーにデータが描画されていました。コンテンツをトレース/エクスポートし、他のブラウザーでテストすることで、すべてが正常であることがわかりました。しかし、Safariでは、この特定のバッファーの描画をメインコンテキストにスキップします。


うん!大きなキャンバスを「許可」として使用するため、Safariはキャンバスの描画をスキップします。上記で投稿した最大寸法を確認してください!それは最大です。このサファリ/デバイス上のキャンバス。
ダドー2014年

あなたのサイズはかなり恣意的ですよね?ドキュメントはありますか?あなたのテストプロセスは何でしたか?
NodeNodeNode 2014年

3

プログラムで制限を見つけようとしました。35000から始まるキャンバスサイズを設定し、有効なサイズが見つかるまで100ずつ下げます。すべてのステップで、右下のピクセルを書き込んでから読み取ります。それは動作します-注意してください。

幅または高さのいずれかがこのように低い値(たとえば、10-200)に設定されている場合、速度は許容範囲ですget_max_canvas_size('height', 20)

しかし、幅や高さなしで呼び出された場合get_max_canvas_size()、作成されたキャンバスは非常に大きくなるため、1ピクセルの色の読み取りが非常に遅くなり、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;
  }
}


1
この大きなキャンバスの作成の失敗が静かで、検出する方法がないのは本当に異常です...あなたの側では決して悪いことではありません、それはブラウザが私たちに飛び付くのは奇妙なことです
Colin D

@ColinD同意する。それはどこかにある小さな情報のほんの一部です。そうでしょう。そして、そうすべきです。
TimoKähkönen2017

3

WebGLキャンバスを使用している場合、ブラウザー(デスクトップを含む)は、基礎となるバッファーのサイズに追加の制限を課します。キャンバスが16,000x16,000のように大きい場合でも、ほとんどのブラウザーはより小さな(4096x4096としましょう)画像をレンダリングして拡大します。それは醜いピクセル化などを引き起こすかもしれません。

誰かがそれを必要とする場合は、指数検索を使用してその最大サイズを決定するためにいくつかのコードを書きました。determineMaxCanvasSize()興味のある機能です。

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/


スケールアップ動作に関する公式ドキュメントはありますか?
Magnus Lind Oxlund

1
@MagnusLindOxlund回答からの情報は実験的に決定されています。クイック検索の後に見つけた最も近いものは次のとおりですkhronos.org/registry/webgl/specs/latest/1.0/#2.2と言って:「上の制約は、キャンバス要素がWebページで消費するスペースの量を変更しません"描画バッファのサイズの制限について話しているとき。WebGL標準では、canvas要素が描画バッファーをどのように表示することになっているのかについて、詳細な説明は行われていないようです。
のMichał

1

それをチャンクにして、JavaScriptで必要な数の小さなキャンバスを自動追加して、適切なキャンバスに要素を描画することができます。最終的にはまだメモリが不足する可能性がありますが、単一のキャンバスの制限によって取得できます。


0

可能な最大サイズを検出する方法はわかりませんが、特定のキャンバスサイズが機能するかどうかは、ピクセルを塗りつぶしてカラーを読み取ることで検出できます。キャンバスがレンダリングされていない場合、返される色は一致しません。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);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.