亀岡的プログラマ日記

京都のベッドタウン、亀岡よりだらだらとお送りいたします。

WritableBitmapをちびちびさわってみる。その1。

WritableBitmapを、触らないまでも多分解説しないといけない空気なので、こっそり勉強始めるの巻。

いや、なんというかね、WritableBitmapはSilverlightのをみててこりゃ簡単だ、と思ってWPF見たらひっくり返るっていうのが恒例のパターンだと思うのですが。WritableなBimapとはいえ、ピクセルへ配列に書きこむプロパティすらありません。ひぃ。
参考:
SIlverlight

WriteableBitmap クラス (System.Windows.Media.Imaging)


WPF

WriteableBitmap クラス (System.Windows.Media.Imaging)

そんなこんなで、まずは簡単なグレースケールの書き込みから。と言ってもコンストラクタから相当クセモノです。

public WriteableBitmap(
	int pixelWidth, //ビットマップの幅。
	int pixelHeight,//ビットマップの高さ。
	double dpiX,//ビットマップの水平dots per inch (dpi)。
	double dpiY,//ビットマップの垂直dots per inch (dpi)。
	PixelFormat pixelFormat,//ビットマップの PixelFormat。
	BitmapPalette palette//ビットマップの BitmapPalette。
)

幅、高さは普通に指定します。DPIはシステムのDPIを使えばいいのですが、まぁよほど何かがない限り96dpiでしょう、今のところ。本当はWindowsAPIを使って取ってくるのがベターなんでしょうけれどね。

問題は次です。PixelFormatはPixelFormatsクラスからプロパティ値として取ってくるのがよいでしょう。普通作る必要はないです。

続いてはBitmapPalette。これも一覧はBitmapPa;ettesクラスから取得します。

とはいえ、これはPixelFormatsからIndex付きのビットマップを使うとき以外には無視してよいので、普通に使う分にはnullでOKです。

それでは、単純なグレースケール用のWritableBitmapを初期化してみましょう。

            const int COLS = 48;
            const int ROWS = 48;
            var bitmap = new WriteableBitmap(COLS, ROWS, 96, 96,
                                     PixelFormats.Gray8, null);

Gray8は8bit = 1byteで1ピクセルなので、扱いが楽なんですよね。
さてさて、それでは色をつけてみましょう。まあとりあえずグラデーションしてみましょうか。

まず色データを放り込むためにbyte型の配列を用意します。WritableBitmapは行と列を区別してくれるような優しさは有りませんので、行と列は自分で管理します。例えば、上からグラデーションするような色を作成するのは以下のようになります。

            byte[] pixels = new byte[COLS * ROWS];

            for (int row = 0; row < ROWS; row++)
            {
                for (int col = 0; col < COLS; col++)
                {
                    int index = /*行*/row * COLS + /*列*/col;

                    pixels[index] = (byte)(0xFF * row / (double)(ROWS-1));
                }
            }

最後に書き込みです。WritePixelメソッドを使います。

            bitmap.WritePixels(
                new Int32Rect(0, 0, COLS, ROWS), //書きこむ領域(ここでは全体)
                pixels, //書きこむデータ
                COLS,   //列幅
                0       //オフセット
                );

単純なデータだとやりやすいですね!コレが複雑いなると、そしてネイティブと連携し始めるとちょいと大変なのですが。

続く。