雑多なブログ

音楽や語学、プログラム関連の話題について書いています

Canvasの画像のピクセルデータの書き込み

Canvasピクセルデータを取り扱う場合は、ImageDataオブジェクトを使用していろいろな操作を行います。

Canvasピクセルデータは次の通り

1ピクセルは、width x height x 4byte のデータがあります。
4byteは何の情報かというと、下記の色の情報を持っています。

R ... 赤
G ... 緑
B ... 青
A ... アルファ

ピクセルデータ自体は画像のピクセルデータ自体は2次元のデータとなっていますが、ImageDataでは1次元の形式でデータが格納されています。そのため、各ピクセルを取得するには下記の計算式で対象のピクセルデータのインデックスを取得します。

(height * y + x) * 4

読み込んだ画像をピクセルごとに書き込む例

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas draw image file</title>

<script>
function draw() {
    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");

    var canvas_buf = document.createElement("canvas");
    canvas_buf.setAttribute("width", 300);
    canvas_buf.setAttribute("height", 250);
    var ctx_buf = canvas_buf.getContext("2d");

    var src_img = new Image(300, 250);
    src_img.src = './music_tympani_fortissimo_fffff.png';
    src_img.addEventListener('load', () => {
        ctx_buf.fillStyle = "#fff";
        ctx_buf.fillRect(0, 0, 300, 250);
        ctx_buf.drawImage(src_img, 0, 0, 300, 250);
        src = ctx_buf.getImageData(0, 0, 300, 250);

        var img = ctx.createImageData(300, 250);

        for (var y = 0; y < 250; y++) {
            for (var x = 0; x < 300; x++) {
                var i = (y * 300 + x) * 4;
                img.data[i + 0] = src.data[i + 0];
                img.data[i + 1] = src.data[i + 1];
                img.data[i + 2] = src.data[i + 2];
                img.data[i + 3] = 0xff;
            }
        }

        ctx.putImageData(img, 0, 0);
    })
}
</script>

</head>
<body onload="draw()">
<canvas id="canvas" width="300" height="250" style="width:300px;height:250px"></canvas>
</body>
</html>

サンプルで使用した画像(いらすとや) f:id:uc_ebuc:20200801221150p:plain www.irasutoya.com

参考情報 developer.mozilla.org

ちょっと分かりづらい。というか、あとで見返した時に自分が分からなくなりそうなのでそのうち更新します。