ハーフトーン処理(ディザ法)

寄稿:東條遼平

2値でグラデーションを表現

ハーフトーン処理とは黒と白つまり輝度が0と255の色だけを用いてハーフトーン(中間色)を表現しようという技術で,2値しか出力できない表示装置でなんとかグレースケールを表現しようとしたものです.具体的には目の錯覚というか,点の密度が大きいところは濃く見え,小さいところは薄く見える事を利用しています.

ディザ法とはハーフトーン処理の技術の1つで,グレースケールの画像を小さいブロックに分割し,それにマスクを掛けて閾値を越えたピクセルを白,下回ったものを黒というように処理しています.ディザ法において閾値のパターンはいろいろあり,分割するブロックの大きさもいろいろあるようですが,今回4×4のブロックに分け,Bayer型のパターンを使う事にします.

img44.png

4×4のマス目の中に0から15までの値があります.また,画像の方も4×4のブロックに分割しているので,全く同じ大きさです.ですから対応するパターンを閾値と考えます.ただし,輝度は256階調なのでそれに合わせるためにパターンの値を16倍して8を足します.例えば4×4のブロックのピクセルが全て128だったとしたら次のようになります.

img45.png

以上がディザ法の説明ですが,実装するにあたって実際に画像を分割する必要はありません. x,yそれぞれの座標を4で割った余りが比較すべきパターンの座標と考えれば良いです.例えば(34, 133)の座標であれば4で割ったあまりは(2, 1)ですので14に対応します.それではソースコードを見てみます.

int bayerpattern[] = { 0,  8,  2, 10,
                      12,  4, 14,  6,
                       3, 11,  1,  9,
                      15,  7, 13,  5};
int i, j;

for(i=0; i<img->height; i++){
  for(j=0; j<img->width; j++){
    if((bayerpattern[(i%4)*4 + (j%4)]*16 + 8) 
                 <= img->rgb[i*img->width + j].r){
      img->rgb[i*img->width + j].r =
      img->rgb[i*img->width + j].g =
      img->rgb[i*img->width + j].b = 255;
    }else{
      img->rgb[i*img->width + j].r =
      img->rgb[i*img->width + j].g =
      img->rgb[i*img->width + j].b = 0;
    }
  }
}

比較しているだけなので,特に難しいところは無いと思います.

ディザ法の説明は以上ですが,グレースケールではなくカラー画像に対してディザ法を適用すると面白い結果が得られます.RGBそれぞれに対してハーフトーン処理を行うと,RGBそれぞれの値は0か255しか取らないので, 2×2×2で合計8色しか使っていないにも関わらず,意外と質は低下しません.これを利用してフルカラー画像を8色に減色することができます.減色を行うことでそれまで1ピクセルを24ビットで表していたのが, 3ビットで表現できるようになり,画像のサイズを小さくすることができます.ただし,本プログラムではビット数は減らしていないため,残念ながらサイズは小さくなりません.

Valid XHTML 1.1! home > コンピュータ > プログラミング >
リロード   新規 編集 凍結 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS
Modified by 物理のかぎプロジェクト PukiWiki 1.4.5_1 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-jiPowered by PHP 5.3.29HTML convert time to 0.009 sec.