1. ホーム
  2. ハイパーリンク

[解決済み】HTML5キャンバスに1つのピクセルを設定する最良の方法は何ですか?

2022-04-12 10:30:51

質問

HTML5 Canvasには、1ピクセルを明示的に設定するメソッドがありません。

非常に短い行を使用してピクセルを設定することは可能かもしれませんが、その場合、アンチエイリアスやラインキャップが干渉する可能性があります。

別の方法として、小さな ImageData オブジェクトを使用します。

context.putImageData(data, x, y)

をクリックすると、所定の位置に配置されます。

どなたか、効率的で確実な方法を教えてください。

どのように解決するのですか?

ベストコンテンダーは2つあります。

  1. 1×1の画像データを作成し、色を設定し putImageData を配置する。

    var id = myContext.createImageData(1,1); // only do this once per page
    var d  = id.data;                        // only do this once per page
    d[0]   = r;
    d[1]   = g;
    d[2]   = b;
    d[3]   = a;
    myContext.putImageData( id, x, y );     
    
    
  2. 使用方法 fillRect() を使用してピクセルを描画します (エイリアシングの問題は発生しないはずです)。

    ctx.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")";
    ctx.fillRect( x, y, 1, 1 );
    
    

こちらでスピードテストができます。 http://jsperf.com/setting-canvas-pixel/9 またはこちら https://www.measurethat.net/Benchmarks/Show/1664/1

最大限のスピードを出すために、気になるブラウザに対してテストをすることをお勧めします。 2017年7月現在 fillRect() は、Firefox v54とChrome v59(Win7x64)で5~6倍高速化されています。

その他、もっとくだらない代物もあります。

  • 使用 getImageData()/putImageData() をキャンバス全体に適用すると、他のオプションに比べて約 100 倍遅くなります。

  • カスタム画像を作成するには、データURLと drawImage() で表示します。

    var img = new Image;
    img.src = "data:image/png;base64," + myPNGEncoder(r,g,b,a);
    // Writing the PNGEncoder is left as an exercise for the reader
    
    
  • 別の画像かキャンバスを作成し、必要なピクセルをすべて入力して使用します。 drawImage() を使用して、必要なピクセルだけを横方向にブリットします。これはおそらく非常に高速ですが、必要なピクセルを事前に計算する必要があるという制約があります。

私のテストでは、canvas コンテキストの保存と復元を試みていないことに注意してください。 fillStyle の速度が低下します。 fillRect() のパフォーマンスを向上させることができます。また、私は何もないところから始めたり、各テストで全く同じピクセルのセットをテストしているわけではないことに注意してください。