ディザ行列

ディザ法は少ない階調で、擬似的により多くの階調を表現するための画像処理の手法です。たとえば、赤と黄しかない場合にオレンジ色を表現するには、赤と黄を交互にならべることにより、全体的にオレンジ色に見せるわけです。ただ、十分な解像度がないとかえって汚くなります。一昔前のCGは16色のパレットと、ディザを駆使したものがたくさんありました。現在ではフルカラー化が進み、需要は余りなくなってきたようではありますが、GIF画像や、ゲーム用のテクスチャなどではデータ量を減らすため、相変わらず256色やハイカラーの画像が使われております。そのため、ディザ法はまだしばらく使われるものと思います。また、同様の目的を実現するのに誤差拡散法という方法もあります。

 

ディザ行列の例

4階調のディザ行列

  0   2
  3   1

16階調のディザ行列

0 8 2 10
12 4 14 6
3 11 1 9
15 7 13 5

 

ディザ行列を使った処理の例

例として、座標(x, y)にある24bitフルカラーのピクセル(r, g, b)を15bitハイカラーに変換するプログラムを示します。

// 8階調ディザ行列のテーブル
int DitherTable8[16] = {
    0, 4, 1, 5,
    6, 2, 7, 3,
    1, 5, 0, 4,
    7, 3, 6, 2,
};

// 24bitColorのRGBの値から、ハイカラーの値を求める
WORD GetDitherColor(int x, int y, int r, int g, int b)
{
    int d = DitherTable8[((y & 3) << 2) | (x & 3)];
    // 上記のテーブルを使わない以下の方法もある。
    // d = (((y & 1) | (((x ^ y) & 1) << 1)) << 1) | (((x ^ y) & 2 ) >> 1);

    // ディザを使用するため、255->248 に変更し、
    // ディザ値を +d した時に 255 を超えないようにする。
    r = (r * 249 >> 8) + d;
    g = (g * 249 >> 8) + d;
    b = (b * 249 >> 8) + d;
    return ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);

    //より高速化が必要なら ((x * 249 >> 8) + d) >> 3) のテーブルを作成する。
    // その場合テーブルサイズは 256*16 バイト必要となる。
}