プログラミング C# - 翔ソフトウェア (Sho's)

C#/.NET/ソフトウェア開発など

ImageData によるピクセル単位の描画

typescriptlogo.png

今回は TypeScript による JavaScript で、HTML5Canvas 上の ImageData にピクセル単位の描画を行う例をあげてみる。

描画自体は、特に TypeScript に依存した内容ではないが、TypeScript に慣れるためのサンプルという意味合いだ。

HTML5Canvas に ImageData を作成してピクセル単位の描画を行う

前回を参考に、Visual Studio で「TypeScript を使用した HTML アプリケーション」を作成してやってみよう。

先ず setpixelsample.html という HTML ファイルを用意する。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>SetPixel Sample</title>
    <script src="setpixelsample.js"></script>
</head>
<body onload="SetPixelSample.Program.run()">
    <canvas width="500" height="500"></canvas>
</body>
</html>

この HTML ファイルでは、setpixelsample.js という JavaScript ファイルを組み込んでいる。そこで setpixelsample.ts という TypeScript ファイルを追加する。

また、onload="SetPixelSample.Program.run()" という記述があるが、このメソッドも setpixelsample.ts 内に用意する。

そして、このメソッド内から HTML 内の canvas に描画を行うこととする。

canvas オブジェクトを取得し、その中に (canvas オブジェクトと同じ幅と高さの) ImageData オブジェクトを作成するには、createImageData を使う。

    var canvas    = <HTMLCanvasElement>document.querySelector("canvas");
	var context   = canvas.getContext("2d");
	var imageData = context.createImageData(canvas.width, canvas.height);

また、ImageData オブジェクトに任意の色のピクセルを置くには、次のように ImageData オブジェクトの data に赤、緑、青、アルファ値の順で1バイトずつ書き込めば良い。

    // ImageData の指定した座標の 1 ピクセルを指定した色にする
    private static setPixel(imageData: ImageData, x: number, y: number, red: number, green: number, blue: number, alpha: number = 0xff) {
        // 指定した座標のピクセルが ImageData の data のどの位置にあるかを計算
        var index = (x + y * imageData.width) * 4;

        // その位置から、赤、緑、青、アルファ値の順で1バイトずつ書き込むことで、ピクセルがその色になる
        imageData.data[index + 0] = red  ;
        imageData.data[index + 1] = green;
        imageData.data[index + 2] = blue ;
        imageData.data[index + 3] = alpha;
    }

任意の色のピクセルが置かれた ImageData オブジェクトを描画するには putImageData を使う。

    // ImageData を描画
    context.putImageData(imageData, 0, 0);

ImageData オブジェクトにランダムに 100,000 個のピクセルを置いて描画するサンプルを作ってみると次のようになる (setpixelsample.ts)。

module SetPixelSample {
    export class Program {
        static run() {
            var canvas    = <HTMLCanvasElement>document.querySelector("canvas");
            var context   = canvas.getContext("2d");
            var imageData = context.createImageData(canvas.width, canvas.height);

            // ImageData にランダムにピクセルを置く
            Program.setRandomPixels(canvas, imageData);

            // ImageData を描画
            context.putImageData(imageData, 0, 0);
        }

        // ImageData のランダムな座標のピクセルをランダムな色にする
        private static setRandomPixels(canvas: HTMLCanvasElement, imageData: ImageData) {
            for (var index = 0; index < 100000; index++) {
                var x     = Program.randomInteger(canvas.height);
                var y     = Program.randomInteger(canvas.width );
                var red   = Program.randomInteger(0x100        );
                var green = Program.randomInteger(0x100        );
                var blue  = Program.randomInteger(0x100        );
                Program.setPixel(imageData, x, y, red, green, blue);
            }
        }

        // 疑似乱数 (0 から value 未満の整数)
        private static randomInteger(value: number): number {
            return Math.floor(value * Math.random());
        }

        // ImageData の指定した座標の 1 ピクセルを指定した色にする
        private static setPixel(imageData: ImageData, x: number, y: number, red: number, green: number, blue: number, alpha: number = 0xff) {
            // 指定した座標のピクセルが ImageData の data のどの位置にあるかを計算
            var index = (x + y * imageData.width) * 4;

            // その位置から、赤、緑、青、アルファ値の順で1バイトずつ書き込むことで、ピクセルがその色になる
            imageData.data[index + 0] = red  ;
            imageData.data[index + 1] = green;
            imageData.data[index + 2] = blue ;
            imageData.data[index + 3] = alpha;
        }
    }
}

コンパイルして setpixelsample.js を生成し、setpixelsample.html を Internet Explorer 9 以降等の HTML5 対応の Web ブラウザーで表示してみると次のようにランダムな 100,000 個のピクセルが描画される。

setpixelsample.html
setpixelsample.html

実際のサンプルを次の場所に用意した。