ハーフトーン処理(ディザ法) の変更点


 RIGHT:寄稿:東條遼平
 
 * 2値でグラデーションを表現 [#m4aef391]
 
 ハーフトーン処理とは黒と白つまり輝度が0と255の色だけを用いてハーフトーン(中間色)を表現しようという技術で、2値しか出力できない表示装置でなんとかグレースケールを表現しようとしたものです。具体的には目の錯覚というか、点の密度が大きいところは濃く見え、小さいところは薄く見える事を利用しています。
 
 ディザ法とはハーフトーン処理の技術の1つで、グレースケールの画像を小さいブロックに分割し、それにマスクを掛けて閾値を越えたピクセルを白、下回ったものを黒というように処理しています。ディザ法において閾値のパターンはいろいろあり、分割するブロックの大きさもいろいろあるようですが、今回4×4のブロックに分け、Bayer型のパターンを使う事にします。
 
 #ref(img44.png,nolink)
 
 4×4のマス目の中に0から15までの値があります。また、画像の方も4×4のブロックに分割しているので、全く同じ大きさです。ですから対応するパターンを閾値と考えます。ただし、輝度は256階調なのでそれに合わせるためにパターンの値を16倍して8を足します。例えば4×4のブロックのピクセルが全て128だったとしたら次のようになります。
 
 #ref(img45.png,nolink)
 
 以上がディザ法の説明ですが、実装するにあたって実際に画像を分割する必要はありません。 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ビットで表現できるようになり、画像のサイズを小さくすることができます。ただし、本プログラムではビット数は減らしていないため、残念ながらサイズは小さくなりません。
 
 - &ref(main.c);
 - &ref(bitmap.c);
 - &ref(bitmap.h);
 
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.002 sec.